22
33from __future__ import annotations
44
5- from homeassistant .core import Event , HomeAssistant , EventStateChangedData , callback
5+ from homeassistant .components .binary_sensor import BinarySensorEntity
6+ from homeassistant .config_entries import ConfigEntry
67from homeassistant .const import (
78 CONF_NAME ,
8- STATE_UNKNOWN ,
99 CONF_UNIQUE_ID ,
1010 STATE_UNAVAILABLE ,
11+ STATE_UNKNOWN ,
12+ )
13+ from homeassistant .core import Event , EventStateChangedData , HomeAssistant , callback
14+ from homeassistant .helpers import (
15+ device_registry as dr ,
16+ entity_registry as er ,
17+ label_registry as lr ,
1118)
12- from homeassistant .helpers import device_registry as dr , entity_registry as er
13- from homeassistant .helpers .event import async_track_state_change_event
14- from homeassistant .config_entries import ConfigEntry
15- from homeassistant .helpers .typing import ConfigType , DiscoveryInfoType
1619from homeassistant .helpers .entity_platform import (
17- AddEntitiesCallback ,
1820 AddConfigEntryEntitiesCallback ,
21+ AddEntitiesCallback ,
1922)
2023from homeassistant .helpers .entity_registry import EVENT_ENTITY_REGISTRY_UPDATED
21- from homeassistant .components .binary_sensor import BinarySensorEntity
24+ from homeassistant .helpers .event import async_track_state_change_event
25+ from homeassistant .helpers .label_registry import EVENT_LABEL_REGISTRY_UPDATED
26+ from homeassistant .helpers .typing import ConfigType , DiscoveryInfoType
2227
2328from .const import (
24- LOGGER ,
25- CONF_LABEL ,
2629 ATTR_ENTITIES ,
27- CONF_STATE_TO ,
28- CONF_STATE_NOT ,
29- CONF_STATE_TYPE ,
3030 ATTR_ENTITY_NAMES ,
31+ ATTR_LABEL_NAME ,
32+ CONF_LABEL ,
3133 CONF_STATE_LOWER_LIMIT ,
34+ CONF_STATE_NOT ,
35+ CONF_STATE_TO ,
36+ CONF_STATE_TYPE ,
3237 CONF_STATE_UPPER_LIMIT ,
38+ LOGGER ,
3339 StateTypes ,
3440)
3541
@@ -116,6 +122,7 @@ class LabelStateBinarySensor(BinarySensorEntity):
116122 _attr_should_poll = False
117123
118124 _state_dict : dict [str , str ] = {}
125+ _label_name : str = ""
119126
120127 def __init__ (
121128 self ,
@@ -131,7 +138,7 @@ def __init__(
131138 ) -> None :
132139 """Initialize the label state sensor."""
133140 self ._attr_unique_id = unique_id
134- self ._label = label
141+ self ._label_id = label
135142 self ._state_type = state_type
136143 self ._state_to = state_to
137144 self ._state_not = state_not
@@ -142,20 +149,27 @@ def __init__(
142149 self ._unit_of_measurement_mismatch = False
143150
144151 self ._attr_is_on = False
145- self ._attr_extra_state_attributes = {}
146- self ._attr_extra_state_attributes .update (
147- {
148- ATTR_ENTITIES : [],
149- }
152+ self ._attr_extra_state_attributes = {
153+ ATTR_ENTITIES : [],
154+ ATTR_ENTITY_NAMES : [],
155+ ATTR_LABEL_NAME : self ._label_name ,
156+ }
157+ self ._unrecorded_attributes = frozenset (
158+ {ATTR_ENTITIES , ATTR_ENTITY_NAMES , ATTR_LABEL_NAME }
150159 )
151160
152161 async def async_added_to_hass (self ) -> None :
153162 """Handle added to Hass."""
154163
155164 await super ().async_added_to_hass ()
156165
166+ label_reg = lr .async_get (self .hass )
167+ label_entry = label_reg .async_get_label (self ._label_id )
168+ if label_entry is not None :
169+ self ._label_name = label_entry .name
170+
157171 ent_reg = er .async_get (self .hass )
158- entries = er .async_entries_for_label (ent_reg , self ._label )
172+ entries = er .async_entries_for_label (ent_reg , self ._label_id )
159173
160174 for entity_entry in entries :
161175 if entity_entry .entity_id == self .entity_id :
@@ -165,10 +179,10 @@ async def async_added_to_hass(self) -> None:
165179 )
166180 continue
167181 for label in entity_entry .labels :
168- if label == self ._label :
182+ if label == self ._label_id :
169183 LOGGER .debug (
170184 "Found label %s in entity %s" ,
171- self ._label ,
185+ self ._label_id ,
172186 entity_entry .entity_id ,
173187 )
174188
@@ -183,7 +197,7 @@ async def async_added_to_hass(self) -> None:
183197 },
184198 )
185199
186- if entity_entry and self ._label in entity_entry .labels :
200+ if entity_entry and self ._label_id in entity_entry .labels :
187201 self ._async_state_listener (state_event , update_state = False )
188202
189203 self .async_on_remove (
@@ -194,6 +208,13 @@ async def async_added_to_hass(self) -> None:
194208 )
195209 )
196210
211+ self .async_on_remove (
212+ self .hass .bus .async_listen (
213+ EVENT_LABEL_REGISTRY_UPDATED ,
214+ self ._async_label_registry_modified ,
215+ )
216+ )
217+
197218 self .async_on_remove (
198219 self .hass .bus .async_listen (
199220 EVENT_ENTITY_REGISTRY_UPDATED ,
@@ -204,6 +225,22 @@ async def async_added_to_hass(self) -> None:
204225 self ._calc_state ()
205226 self .async_write_ha_state ()
206227
228+ @callback
229+ def _async_label_registry_modified (
230+ self , event : Event [lr .EventLabelRegistryUpdatedData ]
231+ ) -> None :
232+ """Handle label registry update."""
233+ data = event .data
234+ if data ["action" ] == "update" and data ["label_id" ] == self ._label_id :
235+ # Get the label, update the name
236+ label_reg = lr .async_get (self .hass )
237+ label_entry = label_reg .async_get_label (self ._label_id )
238+ if label_entry is not None :
239+ self ._label_name = label_entry .name
240+
241+ self ._calc_state ()
242+ self .async_write_ha_state ()
243+
207244 @callback
208245 def _async_entity_registry_modified (
209246 self , event : Event [er .EventEntityRegistryUpdatedData ]
@@ -215,7 +252,7 @@ def _async_entity_registry_modified(
215252 entity_registry = er .async_get (self .hass )
216253 entity_entry = entity_registry .async_get (data ["entity_id" ])
217254
218- if entity_entry and self ._label in entity_entry .labels :
255+ if entity_entry and self ._label_id in entity_entry .labels :
219256 if entity_entry .entity_id == self .entity_id :
220257 LOGGER .debug (
221258 "We don't watch ourself %s" ,
@@ -232,7 +269,7 @@ def _async_entity_registry_modified(
232269 )
233270 LOGGER .debug (
234271 "Found label %s in entity %s" ,
235- self ._label ,
272+ self ._label_id ,
236273 entity_entry .entity_id ,
237274 )
238275
@@ -273,7 +310,7 @@ def _calc_state(self) -> None:
273310 for entity_id in self ._state_dict .keys ():
274311 # Check if the state still has the label
275312 entity_entry = entity_registry .async_get (entity_id )
276- if entity_entry and self ._label in entity_entry .labels :
313+ if entity_entry and self ._label_id in entity_entry .labels :
277314 entity_state = self ._state_dict [entity_id ]
278315
279316 if (
@@ -290,7 +327,7 @@ def _calc_state(self) -> None:
290327 for entity_id in self ._state_dict .keys ():
291328 # Check if the state still has the label
292329 entity_entry = entity_registry .async_get (entity_id )
293- if entity_entry and self ._label in entity_entry .labels :
330+ if entity_entry and self ._label_id in entity_entry .labels :
294331 entity_state = self ._state_dict [entity_id ]
295332
296333 if (
@@ -307,7 +344,7 @@ def _calc_state(self) -> None:
307344 for entity_id in self ._state_dict .keys ():
308345 # Check if the state still has the label
309346 entity_entry = entity_registry .async_get (entity_id )
310- if entity_entry and self ._label in entity_entry .labels :
347+ if entity_entry and self ._label_id in entity_entry .labels :
311348 entity_state = self ._state_dict [entity_id ]
312349
313350 try :
@@ -384,6 +421,7 @@ def _calc_state(self) -> None:
384421 self ._attr_is_on = state_is_on
385422 self ._attr_extra_state_attributes [ATTR_ENTITIES ] = entities_on
386423 self ._attr_extra_state_attributes [ATTR_ENTITY_NAMES ] = entity_names
424+ self ._attr_extra_state_attributes [ATTR_LABEL_NAME ] = self ._label_name
387425
388426 def _get_device_or_entity_name (
389427 self ,
0 commit comments