Home Assistant Unofficial Reference 2024.12.1
handler.py
Go to the documentation of this file.
1 """Handle MySensors messages."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Callable
6 
7 from mysensors import Message
8 from mysensors.const import SYSTEM_CHILD_ID
9 
10 from homeassistant.const import Platform
11 from homeassistant.core import HomeAssistant, callback
12 from homeassistant.helpers.dispatcher import async_dispatcher_send
13 from homeassistant.util import decorator
14 
15 from .const import CHILD_CALLBACK, NODE_CALLBACK, DevId, GatewayId
16 from .entity import get_mysensors_devices
17 from .helpers import (
18  discover_mysensors_node,
19  discover_mysensors_platform,
20  validate_set_msg,
21 )
22 
23 HANDLERS: decorator.Registry[
24  str, Callable[[HomeAssistant, GatewayId, Message], None]
25 ] = decorator.Registry()
26 
27 
28 @HANDLERS.register("set")
29 @callback
30 def handle_set(hass: HomeAssistant, gateway_id: GatewayId, msg: Message) -> None:
31  """Handle a mysensors set message."""
32  validated = validate_set_msg(gateway_id, msg)
33  _handle_child_update(hass, gateway_id, validated)
34 
35 
36 @HANDLERS.register("internal")
37 @callback
38 def handle_internal(hass: HomeAssistant, gateway_id: GatewayId, msg: Message) -> None:
39  """Handle a mysensors internal message."""
40  internal = msg.gateway.const.Internal(msg.sub_type)
41  if (handler := HANDLERS.get(internal.name)) is None:
42  return
43  handler(hass, gateway_id, msg)
44 
45 
46 @HANDLERS.register("I_BATTERY_LEVEL")
47 @callback
49  hass: HomeAssistant, gateway_id: GatewayId, msg: Message
50 ) -> None:
51  """Handle an internal battery level message."""
52  _handle_node_update(hass, gateway_id, msg)
53 
54 
55 @HANDLERS.register("I_HEARTBEAT_RESPONSE")
56 @callback
57 def handle_heartbeat(hass: HomeAssistant, gateway_id: GatewayId, msg: Message) -> None:
58  """Handle an heartbeat."""
59  _handle_node_update(hass, gateway_id, msg)
60 
61 
62 @HANDLERS.register("I_SKETCH_NAME")
63 @callback
65  hass: HomeAssistant, gateway_id: GatewayId, msg: Message
66 ) -> None:
67  """Handle an internal sketch name message."""
68  _handle_node_update(hass, gateway_id, msg)
69 
70 
71 @HANDLERS.register("I_SKETCH_VERSION")
72 @callback
74  hass: HomeAssistant, gateway_id: GatewayId, msg: Message
75 ) -> None:
76  """Handle an internal sketch version message."""
77  _handle_node_update(hass, gateway_id, msg)
78 
79 
80 @HANDLERS.register("presentation")
81 @callback
83  hass: HomeAssistant, gateway_id: GatewayId, msg: Message
84 ) -> None:
85  """Handle an internal presentation message."""
86  if msg.child_id == SYSTEM_CHILD_ID:
87  discover_mysensors_node(hass, gateway_id, msg.node_id)
88 
89 
90 @callback
92  hass: HomeAssistant, gateway_id: GatewayId, validated: dict[Platform, list[DevId]]
93 ) -> None:
94  """Handle a child update."""
95  signals: list[str] = []
96 
97  # Update all platforms for the device via dispatcher.
98  # Add/update entity for validated children.
99  for platform, dev_ids in validated.items():
100  devices = get_mysensors_devices(hass, platform)
101  new_dev_ids: list[DevId] = []
102  for dev_id in dev_ids:
103  if dev_id in devices:
104  signals.append(CHILD_CALLBACK.format(*dev_id))
105  else:
106  new_dev_ids.append(dev_id)
107  if new_dev_ids:
108  discover_mysensors_platform(hass, gateway_id, platform, new_dev_ids)
109  for signal in set(signals):
110  # Only one signal per device is needed.
111  # A device can have multiple platforms, ie multiple schemas.
112  async_dispatcher_send(hass, signal)
113 
114 
115 @callback
117  hass: HomeAssistant, gateway_id: GatewayId, msg: Message
118 ) -> None:
119  """Handle a node update."""
120  signal = NODE_CALLBACK.format(gateway_id, msg.node_id)
121  async_dispatcher_send(hass, signal)
dict[DevId, MySensorsChildEntity] get_mysensors_devices(HomeAssistant hass, Platform domain)
Definition: entity.py:139
None handle_sketch_version(HomeAssistant hass, GatewayId gateway_id, Message msg)
Definition: handler.py:75
None handle_heartbeat(HomeAssistant hass, GatewayId gateway_id, Message msg)
Definition: handler.py:57
None _handle_node_update(HomeAssistant hass, GatewayId gateway_id, Message msg)
Definition: handler.py:118
None handle_set(HomeAssistant hass, GatewayId gateway_id, Message msg)
Definition: handler.py:30
None handle_presentation(HomeAssistant hass, GatewayId gateway_id, Message msg)
Definition: handler.py:84
None handle_internal(HomeAssistant hass, GatewayId gateway_id, Message msg)
Definition: handler.py:38
None handle_battery_level(HomeAssistant hass, GatewayId gateway_id, Message msg)
Definition: handler.py:50
None _handle_child_update(HomeAssistant hass, GatewayId gateway_id, dict[Platform, list[DevId]] validated)
Definition: handler.py:93
None handle_sketch_name(HomeAssistant hass, GatewayId gateway_id, Message msg)
Definition: handler.py:66
None discover_mysensors_platform(HomeAssistant hass, GatewayId gateway_id, str platform, list[DevId] new_devices)
Definition: helpers.py:59
None discover_mysensors_node(HomeAssistant hass, GatewayId gateway_id, int node_id)
Definition: helpers.py:76
dict[Platform, list[DevId]] validate_set_msg(GatewayId gateway_id, Message msg)
Definition: helpers.py:178
None async_dispatcher_send(HomeAssistant hass, str signal, *Any args)
Definition: dispatcher.py:193