Home Assistant Unofficial Reference 2024.12.1
trigger.py
Go to the documentation of this file.
1 """Trigger an automation when a LiteJet switch is released."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Callable
6 from datetime import datetime
7 from typing import cast
8 
9 from pylitejet import LiteJet
10 import voluptuous as vol
11 
12 from homeassistant.const import CONF_PLATFORM
13 from homeassistant.core import CALLBACK_TYPE, HassJob, HomeAssistant, callback
15 from homeassistant.helpers.event import track_point_in_utc_time
16 from homeassistant.helpers.trigger import TriggerActionType, TriggerInfo
17 from homeassistant.helpers.typing import ConfigType
18 import homeassistant.util.dt as dt_util
19 
20 from .const import DOMAIN
21 
22 CONF_NUMBER = "number"
23 CONF_HELD_MORE_THAN = "held_more_than"
24 CONF_HELD_LESS_THAN = "held_less_than"
25 
26 TRIGGER_SCHEMA = cv.TRIGGER_BASE_SCHEMA.extend(
27  {
28  vol.Required(CONF_PLATFORM): "litejet",
29  vol.Required(CONF_NUMBER): cv.positive_int,
30  vol.Optional(CONF_HELD_MORE_THAN): vol.All(
31  cv.time_period, cv.positive_timedelta
32  ),
33  vol.Optional(CONF_HELD_LESS_THAN): vol.All(
34  cv.time_period, cv.positive_timedelta
35  ),
36  }
37 )
38 
39 
41  hass: HomeAssistant,
42  config: ConfigType,
43  action: TriggerActionType,
44  trigger_info: TriggerInfo,
45 ) -> CALLBACK_TYPE:
46  """Listen for events based on configuration."""
47  trigger_data = trigger_info["trigger_data"]
48  number = cast(int, config[CONF_NUMBER])
49  held_more_than = config.get(CONF_HELD_MORE_THAN)
50  held_less_than = config.get(CONF_HELD_LESS_THAN)
51  pressed_time = None
52  cancel_pressed_more_than: Callable | None = None
53  job = HassJob(action)
54 
55  @callback
56  def call_action() -> None:
57  """Call action with right context."""
58  hass.async_run_hass_job(
59  job,
60  {
61  "trigger": {
62  **trigger_data,
63  CONF_PLATFORM: "litejet",
64  CONF_NUMBER: number,
65  CONF_HELD_MORE_THAN: held_more_than,
66  CONF_HELD_LESS_THAN: held_less_than,
67  "description": f"litejet switch #{number}",
68  }
69  },
70  )
71 
72  # held_more_than and held_less_than: trigger on released (if in time range)
73  # held_more_than: trigger after pressed with calculation
74  # held_less_than: trigger on released with calculation
75  # neither: trigger on pressed
76 
77  @callback
78  def pressed_more_than_satisfied(now: datetime) -> None:
79  """Handle the LiteJet's switch's button pressed >= held_more_than."""
80  call_action()
81 
82  def pressed() -> None:
83  """Handle the press of the LiteJet switch's button."""
84  nonlocal cancel_pressed_more_than, pressed_time
85  nonlocal held_less_than, held_more_than
86  pressed_time = dt_util.utcnow()
87  if held_more_than is None and held_less_than is None:
88  hass.add_job(call_action)
89  if held_more_than is not None and held_less_than is None:
90  cancel_pressed_more_than = track_point_in_utc_time(
91  hass, pressed_more_than_satisfied, dt_util.utcnow() + held_more_than
92  )
93 
94  def released() -> None:
95  """Handle the release of the LiteJet switch's button."""
96  nonlocal cancel_pressed_more_than, pressed_time
97  nonlocal held_less_than, held_more_than
98  if pressed_time is None:
99  return
100  if cancel_pressed_more_than is not None:
101  cancel_pressed_more_than()
102  cancel_pressed_more_than = None
103  held_time = dt_util.utcnow() - pressed_time
104 
105  if (
106  held_less_than is not None
107  and held_time < held_less_than
108  and (held_more_than is None or held_time > held_more_than)
109  ):
110  hass.add_job(call_action)
111 
112  system: LiteJet = hass.data[DOMAIN]
113 
114  system.on_switch_pressed(number, pressed)
115  system.on_switch_released(number, released)
116 
117  @callback
118  def async_remove() -> None:
119  """Remove all subscriptions used for this trigger."""
120  system.unsubscribe(pressed)
121  system.unsubscribe(released)
122 
123  return async_remove
CALLBACK_TYPE async_attach_trigger(HomeAssistant hass, ConfigType config, TriggerActionType action, TriggerInfo trigger_info)
Definition: trigger.py:45
None async_remove(HomeAssistant hass, str intent_type)
Definition: intent.py:90