9
9
import voluptuous as vol
10
10
11
11
from homeassistant .config_entries import ConfigEntry
12
- from homeassistant .const import CONF_ENTITY_ID
13
12
from homeassistant .core import (
14
13
HomeAssistant ,
15
14
callback ,
16
15
Event ,
16
+ split_entity_id ,
17
17
)
18
18
from homeassistant .exceptions import TemplateError
19
19
from homeassistant .helpers .entity import Entity
64
64
DOMAIN ,
65
65
DATA ,
66
66
ATTR_BATTERY_LOW_THRESHOLD ,
67
+ CONF_SOURCE_ENTITY_ID ,
67
68
)
68
69
69
- from .common import isfloat
70
+ from .common import validate_is_float
70
71
71
72
from .device import BatteryNotesDevice
72
73
from .coordinator import BatteryNotesCoordinator
@@ -87,22 +88,25 @@ class BatteryNotesBinarySensorEntityDescription(
87
88
88
89
unique_id_suffix : str
89
90
90
-
91
91
PLATFORM_SCHEMA = PLATFORM_SCHEMA .extend (
92
- {vol .Optional (CONF_NAME ): cv .string , vol .Required (CONF_DEVICE_ID ): cv .string }
92
+ {
93
+ vol .Optional (CONF_NAME ): cv .string ,
94
+ vol .Optional (CONF_DEVICE_ID ): cv .string ,
95
+ vol .Optional (CONF_SOURCE_ENTITY_ID ): cv .string ,
96
+ }
93
97
)
94
98
95
-
96
99
@callback
97
100
def async_add_to_device (hass : HomeAssistant , entry : ConfigEntry ) -> str | None :
98
101
"""Add our config entry to the device."""
99
102
device_registry = dr .async_get (hass )
100
103
101
104
device_id = entry .data .get (CONF_DEVICE_ID )
102
105
103
- if device_registry .async_get (device_id ):
104
- device_registry .async_update_device (device_id , add_config_entry_id = entry .entry_id )
105
- return device_id
106
+ if device_id :
107
+ if device_registry .async_get (device_id ):
108
+ device_registry .async_update_device (device_id , add_config_entry_id = entry .entry_id )
109
+ return device_id
106
110
return None
107
111
108
112
async def async_setup_entry (
@@ -133,7 +137,7 @@ async def async_registry_updated(event: Event) -> None:
133
137
# If the tracked battery note is no longer in the device, remove our config entry
134
138
# from the device
135
139
if (
136
- not (entity_entry := entity_registry .async_get (data [CONF_ENTITY_ID ]))
140
+ not (entity_entry := entity_registry .async_get (data ["entity_id" ]))
137
141
or not device_registry .async_get (device_id )
138
142
or entity_entry .device_id == device_id
139
143
):
@@ -152,10 +156,13 @@ async def async_registry_updated(event: Event) -> None:
152
156
)
153
157
)
154
158
155
- device_id = async_add_to_device ( hass , config_entry )
159
+ device : BatteryNotesDevice = hass . data [ DOMAIN ][ DATA ]. devices [ config_entry . entry_id ]
156
160
157
- if not device_id :
158
- return
161
+ if not device .fake_device :
162
+ device_id = async_add_to_device (hass , config_entry )
163
+
164
+ if not device_id :
165
+ return
159
166
160
167
description = BatteryNotesBinarySensorEntityDescription (
161
168
unique_id_suffix = "_battery_low" ,
@@ -315,7 +322,6 @@ def __init__(
315
322
self .coordinator = coordinator
316
323
self .entity_description = description
317
324
self ._attr_unique_id = unique_id
318
- self ._attr_has_entity_name = True
319
325
self ._template_attrs : dict [Template , list [_TemplateAttribute ]] = {}
320
326
321
327
super ().__init__ (coordinator = coordinator )
@@ -328,7 +334,18 @@ def __init__(
328
334
identifiers = device_entry .identifiers ,
329
335
)
330
336
331
- self .entity_id = f"binary_sensor.{ coordinator .device_name .lower ()} _{ description .key } "
337
+ self ._attr_has_entity_name = True
338
+
339
+ if coordinator .source_entity_id and not coordinator .device_id :
340
+ self ._attr_translation_placeholders = {"device_name" : coordinator .device_name + " " }
341
+ self .entity_id = f"binary_sensor.{ coordinator .device_name .lower ()} _{ description .key } "
342
+ elif coordinator .source_entity_id and coordinator .device_id :
343
+ source_entity_domain , source_object_id = split_entity_id (coordinator .source_entity_id )
344
+ self ._attr_translation_placeholders = {"device_name" : coordinator .source_entity_name + " " }
345
+ self .entity_id = f"binary_sensor.{ source_object_id } _{ description .key } "
346
+ else :
347
+ self ._attr_translation_placeholders = {"device_name" : "" }
348
+ self .entity_id = f"binary_sensor.{ coordinator .device_name .lower ()} _{ description .key } "
332
349
333
350
self ._template = template
334
351
self ._state : bool | None = None
@@ -497,9 +514,21 @@ def __init__(
497
514
device_registry = dr .async_get (hass )
498
515
499
516
self .coordinator = coordinator
517
+ self ._attr_has_entity_name = True
518
+
519
+ if coordinator .source_entity_id and not coordinator .device_id :
520
+ self ._attr_translation_placeholders = {"device_name" : coordinator .device_name + " " }
521
+ self .entity_id = f"binary_sensor.{ coordinator .device_name .lower ()} _{ description .key } "
522
+ elif coordinator .source_entity_id and coordinator .device_id :
523
+ source_entity_domain , source_object_id = split_entity_id (coordinator .source_entity_id )
524
+ self ._attr_translation_placeholders = {"device_name" : coordinator .source_entity_name + " " }
525
+ self .entity_id = f"binary_sensor.{ source_object_id } _{ description .key } "
526
+ else :
527
+ self ._attr_translation_placeholders = {"device_name" : "" }
528
+ self .entity_id = f"binary_sensor.{ coordinator .device_name .lower ()} _{ description .key } "
529
+
500
530
self .entity_description = description
501
531
self ._attr_unique_id = unique_id
502
- self ._attr_has_entity_name = True
503
532
504
533
super ().__init__ (coordinator = coordinator )
505
534
@@ -511,8 +540,6 @@ def __init__(
511
540
identifiers = device_entry .identifiers ,
512
541
)
513
542
514
- self .entity_id = f"binary_sensor.{ coordinator .device_name .lower ()} _{ description .key } "
515
-
516
543
async def async_added_to_hass (self ) -> None :
517
544
"""Handle added to Hass."""
518
545
@@ -536,7 +563,7 @@ def _handle_coordinator_update(self) -> None:
536
563
STATE_UNAVAILABLE ,
537
564
STATE_UNKNOWN ,
538
565
]
539
- or not isfloat (wrapped_battery_state .state )
566
+ or not validate_is_float (wrapped_battery_state .state )
540
567
):
541
568
self ._attr_is_on = None
542
569
self ._attr_available = False
0 commit comments