4848from homeassistant .util import dt as dt_util
4949
5050from . import TriggerUpdateCoordinator
51+ from .entity import AbstractTemplateEntity
5152from .helpers import (
5253 async_setup_template_entry ,
5354 async_setup_template_platform ,
@@ -168,11 +169,27 @@ def async_create_preview_binary_sensor(
168169 )
169170
170171
171- class StateBinarySensorEntity (TemplateEntity , BinarySensorEntity , RestoreEntity ):
172+ class AbstractTemplateBinarySensor (
173+ AbstractTemplateEntity , BinarySensorEntity , RestoreEntity
174+ ):
175+ """Representation of a template binary sensor features."""
176+
177+ _entity_id_format = ENTITY_ID_FORMAT
178+
179+ # The super init is not called because TemplateEntity and TriggerEntity will call AbstractTemplateEntity.__init__.
180+ # This ensures that the __init__ on AbstractTemplateEntity is not called twice.
181+ def __init__ (self , config : dict [str , Any ]) -> None : # pylint: disable=super-init-not-called
182+ """Initialize the features."""
183+
184+ self ._attr_device_class = config .get (CONF_DEVICE_CLASS )
185+ self ._template : template .Template = config [CONF_STATE ]
186+ self ._delay_cancel : CALLBACK_TYPE | None = None
187+
188+
189+ class StateBinarySensorEntity (TemplateEntity , AbstractTemplateBinarySensor ):
172190 """A virtual binary sensor that triggers from another sensor."""
173191
174192 _attr_should_poll = False
175- _entity_id_format = ENTITY_ID_FORMAT
176193
177194 def __init__ (
178195 self ,
@@ -182,19 +199,19 @@ def __init__(
182199 ) -> None :
183200 """Initialize the Template binary sensor."""
184201 TemplateEntity .__init__ (self , hass , config , unique_id )
185-
186- self ._attr_device_class = config .get (CONF_DEVICE_CLASS )
187- self ._template : template .Template = config [CONF_STATE ]
188- self ._delay_cancel = None
202+ AbstractTemplateBinarySensor .__init__ (self , config )
189203 self ._delay_on = None
190- self ._delay_on_raw = config .get (CONF_DELAY_ON )
204+ self ._delay_on_template = config .get (CONF_DELAY_ON )
191205 self ._delay_off = None
192- self ._delay_off_raw = config .get (CONF_DELAY_OFF )
206+ self ._delay_off_template = config .get (CONF_DELAY_OFF )
193207
194208 async def async_added_to_hass (self ) -> None :
195209 """Restore state."""
196210 if (
197- (self ._delay_on_raw is not None or self ._delay_off_raw is not None )
211+ (
212+ self ._delay_on_template is not None
213+ or self ._delay_off_template is not None
214+ )
198215 and (last_state := await self .async_get_last_state ()) is not None
199216 and last_state .state not in (STATE_UNKNOWN , STATE_UNAVAILABLE )
200217 ):
@@ -206,20 +223,20 @@ def _async_setup_templates(self) -> None:
206223 """Set up templates."""
207224 self .add_template_attribute ("_state" , self ._template , None , self ._update_state )
208225
209- if self ._delay_on_raw is not None :
226+ if self ._delay_on_template is not None :
210227 try :
211- self ._delay_on = cv .positive_time_period (self ._delay_on_raw )
228+ self ._delay_on = cv .positive_time_period (self ._delay_on_template )
212229 except vol .Invalid :
213230 self .add_template_attribute (
214- "_delay_on" , self ._delay_on_raw , cv .positive_time_period
231+ "_delay_on" , self ._delay_on_template , cv .positive_time_period
215232 )
216233
217- if self ._delay_off_raw is not None :
234+ if self ._delay_off_template is not None :
218235 try :
219- self ._delay_off = cv .positive_time_period (self ._delay_off_raw )
236+ self ._delay_off = cv .positive_time_period (self ._delay_off_template )
220237 except vol .Invalid :
221238 self .add_template_attribute (
222- "_delay_off" , self ._delay_off_raw , cv .positive_time_period
239+ "_delay_off" , self ._delay_off_template , cv .positive_time_period
223240 )
224241
225242 super ()._async_setup_templates ()
@@ -259,12 +276,10 @@ def _set_state(_):
259276 self ._delay_cancel = async_call_later (self .hass , delay , _set_state )
260277
261278
262- class TriggerBinarySensorEntity (TriggerEntity , BinarySensorEntity , RestoreEntity ):
279+ class TriggerBinarySensorEntity (TriggerEntity , AbstractTemplateBinarySensor ):
263280 """Sensor entity based on trigger data."""
264281
265- _entity_id_format = ENTITY_ID_FORMAT
266282 domain = BINARY_SENSOR_DOMAIN
267- extra_template_keys = (CONF_STATE ,)
268283
269284 def __init__ (
270285 self ,
@@ -273,7 +288,8 @@ def __init__(
273288 config : dict ,
274289 ) -> None :
275290 """Initialize the entity."""
276- super ().__init__ (hass , coordinator , config )
291+ TriggerEntity .__init__ (self , hass , coordinator , config )
292+ AbstractTemplateBinarySensor .__init__ (self , config )
277293
278294 for key in (CONF_STATE , CONF_DELAY_ON , CONF_DELAY_OFF , CONF_AUTO_OFF ):
279295 if isinstance (config .get (key ), template .Template ):
@@ -282,7 +298,6 @@ def __init__(
282298
283299 self ._last_delay_from : bool | None = None
284300 self ._last_delay_to : bool | None = None
285- self ._delay_cancel : CALLBACK_TYPE | None = None
286301 self ._auto_off_cancel : CALLBACK_TYPE | None = None
287302 self ._auto_off_time : datetime | None = None
288303
0 commit comments