1 """Handle MySensors devices."""
3 from __future__
import annotations
5 from abc
import abstractmethod
9 from mysensors
import BaseAsyncGateway, Sensor
10 from mysensors.sensor
import ChildSensor
35 _LOGGER = logging.getLogger(__name__)
37 ATTR_CHILD_ID =
"child_id"
38 ATTR_DESCRIPTION =
"description"
39 ATTR_DEVICE =
"device"
40 ATTR_NODE_ID =
"node_id"
41 ATTR_HEARTBEAT =
"heartbeat"
42 MYSENSORS_PLATFORM_DEVICES =
"mysensors_devices_{}"
46 """Representation of a MySensors device."""
51 self, gateway_id: GatewayId, gateway: BaseAsyncGateway, node_id: int
53 """Set up the MySensors node entity."""
54 self.gateway_id: GatewayId = gateway_id
55 self.gateway: BaseAsyncGateway = gateway
56 self.node_id: int = node_id
57 self.
_debouncer_debouncer: Debouncer |
None =
None
61 return self.gateway.sensors[self.node_id]
65 """Return the name of the sketch running on the whole node.
67 The name will be the same for several entities.
69 return self.
_node_node.sketch_name
73 """Return the version of the sketch running on the whole node.
75 The name will be the same for several entities.
77 return self.
_node_node.sketch_version
81 """Name of the whole node.
83 The name will be the same for several entities.
85 return f
"{self.sketch_name} {self.node_id}"
89 """Return the device info."""
91 identifiers={(DOMAIN, f
"{self.gateway_id}-{self.node_id}")},
99 """Return device specific attributes."""
100 node = self.gateway.sensors[self.node_id]
103 ATTR_HEARTBEAT: node.heartbeat,
104 ATTR_NODE_ID: self.node_id,
110 """Update the device."""
113 """Update the device after delay."""
114 if not self._debouncer:
118 cooldown=UPDATE_DELAY,
126 """Register update callback."""
130 NODE_CALLBACK.format(self.gateway_id, self.node_id),
138 hass: HomeAssistant, domain: Platform
139 ) -> dict[DevId, MySensorsChildEntity]:
140 """Return MySensors devices for a hass platform name."""
141 if MYSENSORS_PLATFORM_DEVICES.format(domain)
not in hass.data[DOMAIN]:
142 hass.data[DOMAIN][MYSENSORS_PLATFORM_DEVICES.format(domain)] = {}
143 devices: dict[DevId, MySensorsChildEntity] = hass.data[DOMAIN][
144 MYSENSORS_PLATFORM_DEVICES.format(domain)
150 """Representation of a MySensors entity."""
152 _attr_should_poll =
False
156 gateway_id: GatewayId,
157 gateway: BaseAsyncGateway,
162 """Set up the MySensors child entity."""
163 super().
__init__(gateway_id, gateway, node_id)
164 self.child_id: int = child_id
166 self.value_type: int = value_type
168 self._values: dict[int, Any] = {}
172 """Return the DevId of this device.
174 It is used to route incoming MySensors messages to the correct device/entity.
176 return self.gateway_id, self.node_id, self.child_id, self.value_type
180 return self.
_node_node.children[self.child_id]
184 """Return a unique ID for use in home assistant."""
185 return f
"{self.gateway_id}-{self.node_id}-{self.child_id}-{self.value_type}"
189 """Return the name of this entity."""
192 if child.description:
193 return str(child.description)
194 return f
"{self.node_name} {self.child_id}"
197 """Remove this entity from home assistant."""
198 for platform
in PLATFORM_TYPES:
199 platform_str = MYSENSORS_PLATFORM_DEVICES.format(platform)
200 if platform_str
in self.
hasshass.data[DOMAIN]:
201 platform_dict = self.
hasshass.data[DOMAIN][platform_str]
202 if self.
dev_iddev_id
in platform_dict:
203 del platform_dict[self.
dev_iddev_id]
204 _LOGGER.debug(
"Deleted %s from platform %s", self.
dev_iddev_id, platform)
208 """Return true if entity is available."""
209 return self.value_type
in self._values
213 """Return entity and device specific state attributes."""
214 attr = super().extra_state_attributes
216 assert self.
platformplatform.config_entry
217 attr[ATTR_DEVICE] = self.
platformplatform.config_entry.data[CONF_DEVICE]
219 attr[ATTR_CHILD_ID] = self.child_id
220 attr[ATTR_DESCRIPTION] = self.
_child_child.description
222 attr[ATTR_BATTERY_LEVEL] = self.
_node_node.battery_level
224 set_req = self.gateway.const.SetReq
225 for value_type, value
in self._values.items():
226 attr[set_req(value_type).name] = value
232 """Update the controller with the latest value from a sensor."""
233 set_req = self.gateway.const.SetReq
234 for value_type, value
in self.
_child_child.values.items():
236 "Entity update: %s: value_type %s, value = %s",
244 set_req.V_LOCK_STATUS,
250 self._values[value_type] = STATE_ON
if int(value) == 1
else STATE_OFF
251 elif value_type == set_req.V_DIMMER:
252 self._values[value_type] =
int(value)
254 self._values[value_type] = value
258 """Update the entity."""
263 """Register update callback."""
268 CHILD_CALLBACK.format(*self.
dev_iddev_id),
None async_update_callback(self)
DeviceInfo device_info(self)
None __init__(self, GatewayId gateway_id, BaseAsyncGateway gateway, int node_id)
dict[str, Any] extra_state_attributes(self)
None _async_update_callback(self)
None async_added_to_hass(self)
None async_added_to_hass(self)
None async_will_remove_from_hass(self)
None _async_update_callback(self)
None __init__(self, GatewayId gateway_id, BaseAsyncGateway gateway, int node_id, int child_id, int value_type)
dict[str, Any] extra_state_attributes(self)
None async_write_ha_state(self)
None async_on_remove(self, CALLBACK_TYPE func)
str|UndefinedType|None name(self)
dict[DevId, MySensorsChildEntity] get_mysensors_devices(HomeAssistant hass, Platform domain)
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)