Home Assistant Unofficial Reference 2024.12.1
util.py
Go to the documentation of this file.
1 """Yale util functions."""
2 
3 from __future__ import annotations
4 
5 from datetime import datetime, timedelta
6 from functools import partial
7 
8 import aiohttp
9 from yalexs.activity import ACTION_DOORBELL_CALL_MISSED, Activity, ActivityType
10 from yalexs.doorbell import DoorbellDetail
11 from yalexs.lock import LockDetail
12 from yalexs.manager.const import ACTIVITY_UPDATE_INTERVAL
13 
14 from homeassistant.core import HomeAssistant, callback
15 from homeassistant.helpers import aiohttp_client
16 
17 from . import YaleData
18 
19 TIME_TO_DECLARE_DETECTION = timedelta(seconds=ACTIVITY_UPDATE_INTERVAL.total_seconds())
20 
21 
22 @callback
23 def async_create_yale_clientsession(hass: HomeAssistant) -> aiohttp.ClientSession:
24  """Create an aiohttp session for the yale integration."""
25  # Create an aiohttp session instead of using the default one since the
26  # default one is likely to trigger yale's WAF if another integration
27  # is also using Cloudflare
28  return aiohttp_client.async_create_clientsession(hass)
29 
30 
32  activities: set[ActivityType], data: YaleData, detail: DoorbellDetail | LockDetail
33 ) -> Activity | None:
34  """Get the latest state of the sensor."""
35  stream = data.activity_stream
36  if latest := stream.get_latest_device_activity(detail.device_id, activities):
37  return _activity_time_based(latest)
38  return False
39 
40 
41 _RING_ACTIVITIES = {ActivityType.DOORBELL_DING}
42 
43 
45  data: YaleData, detail: DoorbellDetail | LockDetail
46 ) -> Activity | None:
47  """Get the ring/ding state."""
48  stream = data.activity_stream
49  latest = stream.get_latest_device_activity(detail.device_id, _RING_ACTIVITIES)
50  if latest is None or (
51  data.push_updates_connected and latest.action == ACTION_DOORBELL_CALL_MISSED
52  ):
53  return None
54  return _activity_time_based(latest)
55 
56 
57 retrieve_doorbell_motion_activity = partial(
58  retrieve_time_based_activity, {ActivityType.DOORBELL_MOTION}
59 )
60 
61 
62 def _activity_time_based(latest: Activity) -> Activity | None:
63  """Get the latest state of the sensor."""
64  start = latest.activity_start_time
65  end = latest.activity_end_time + TIME_TO_DECLARE_DETECTION
66  if start <= datetime.now() <= end:
67  return latest
68  return None
69 
70 
71 def retrieve_online_state(data: YaleData, detail: DoorbellDetail | LockDetail) -> bool:
72  """Get the latest state of the sensor."""
73  # The doorbell will go into standby mode when there is no motion
74  # for a short while. It will wake by itself when needed so we need
75  # to consider is available or we will not report motion or dings
76  if isinstance(detail, DoorbellDetail):
77  return detail.is_online or detail.is_standby
78  return detail.bridge_is_online
Activity|None retrieve_time_based_activity(set[ActivityType] activities, YaleData data, DoorbellDetail|LockDetail detail)
Definition: util.py:33
aiohttp.ClientSession async_create_yale_clientsession(HomeAssistant hass)
Definition: util.py:23
bool retrieve_online_state(YaleData data, DoorbellDetail|LockDetail detail)
Definition: util.py:71
Activity|None retrieve_ding_activity(YaleData data, DoorbellDetail|LockDetail detail)
Definition: util.py:46
Activity|None _activity_time_based(Activity latest)
Definition: util.py:62