Home Assistant Unofficial Reference 2024.12.1
coordinator.py
Go to the documentation of this file.
1 """Contains the shared Coordinator for Starlink systems."""
2 
3 from __future__ import annotations
4 
5 import asyncio
6 from dataclasses import dataclass
7 from datetime import timedelta
8 import logging
9 from zoneinfo import ZoneInfo
10 
11 from starlink_grpc import (
12  AlertDict,
13  ChannelContext,
14  GrpcError,
15  LocationDict,
16  ObstructionDict,
17  StatusDict,
18  get_sleep_config,
19  location_data,
20  reboot,
21  set_sleep_config,
22  set_stow_state,
23  status_data,
24 )
25 
26 from homeassistant.core import HomeAssistant
27 from homeassistant.exceptions import HomeAssistantError
28 from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
29 
30 _LOGGER = logging.getLogger(__name__)
31 
32 
33 @dataclass
35  """Contains data pulled from the Starlink system."""
36 
37  location: LocationDict
38  sleep: tuple[int, int, bool]
39  status: StatusDict
40  obstruction: ObstructionDict
41  alert: AlertDict
42 
43 
45  """Coordinates updates between all Starlink sensors defined in this file."""
46 
47  def __init__(self, hass: HomeAssistant, name: str, url: str) -> None:
48  """Initialize an UpdateCoordinator for a group of sensors."""
49  self.channel_contextchannel_context = ChannelContext(target=url)
50  self.timezonetimezone = ZoneInfo(hass.config.time_zone)
51  super().__init__(
52  hass,
53  _LOGGER,
54  name=name,
55  update_interval=timedelta(seconds=5),
56  )
57 
58  def _get_starlink_data(self) -> StarlinkData:
59  """Retrieve Starlink data."""
60  channel_context = self.channel_contextchannel_context
61  status = status_data(channel_context)
62  location = location_data(channel_context)
63  sleep = get_sleep_config(channel_context)
64  return StarlinkData(location, sleep, *status)
65 
66  async def _async_update_data(self) -> StarlinkData:
67  async with asyncio.timeout(4):
68  try:
69  result = await self.hasshass.async_add_executor_job(self._get_starlink_data_get_starlink_data)
70  except GrpcError as exc:
71  raise UpdateFailed from exc
72  return result
73 
74  async def async_stow_starlink(self, stow: bool) -> None:
75  """Set whether Starlink system tied to this coordinator should be stowed."""
76  async with asyncio.timeout(4):
77  try:
78  await self.hasshass.async_add_executor_job(
79  set_stow_state, not stow, self.channel_contextchannel_context
80  )
81  except GrpcError as exc:
82  raise HomeAssistantError from exc
83 
84  async def async_reboot_starlink(self) -> None:
85  """Reboot the Starlink system tied to this coordinator."""
86  async with asyncio.timeout(4):
87  try:
88  await self.hasshass.async_add_executor_job(reboot, self.channel_contextchannel_context)
89  except GrpcError as exc:
90  raise HomeAssistantError from exc
91 
92  async def async_set_sleep_schedule_enabled(self, sleep_schedule: bool) -> None:
93  """Set whether Starlink system uses the configured sleep schedule."""
94  async with asyncio.timeout(4):
95  try:
96  await self.hasshass.async_add_executor_job(
97  set_sleep_config,
98  self.datadata.sleep[0],
99  self.datadata.sleep[1],
100  sleep_schedule,
101  self.channel_contextchannel_context,
102  )
103  except GrpcError as exc:
104  raise HomeAssistantError from exc
105 
106  async def async_set_sleep_start(self, start: int) -> None:
107  """Set Starlink system sleep schedule start time."""
108  async with asyncio.timeout(4):
109  try:
110  await self.hasshass.async_add_executor_job(
111  set_sleep_config,
112  start,
113  self.datadata.sleep[1],
114  self.datadata.sleep[2],
115  self.channel_contextchannel_context,
116  )
117  except GrpcError as exc:
118  raise HomeAssistantError from exc
119 
120  async def async_set_sleep_duration(self, end: int) -> None:
121  """Set Starlink system sleep schedule end time."""
122  duration = end - self.datadata.sleep[0]
123  if duration < 0:
124  # If the duration pushed us into the next day, add one days worth to correct that.
125  duration += 1440
126  async with asyncio.timeout(4):
127  try:
128  await self.hasshass.async_add_executor_job(
129  set_sleep_config,
130  self.datadata.sleep[0],
131  duration,
132  self.datadata.sleep[2],
133  self.channel_contextchannel_context,
134  )
135  except GrpcError as exc:
136  raise HomeAssistantError from exc