2626
2727from . import TriggerUpdateCoordinator
2828from .const import CONF_PICTURE
29+ from .entity import AbstractTemplateEntity
2930from .helpers import async_setup_template_entry , async_setup_template_platform
3031from .schemas import (
3132 TEMPLATE_ENTITY_COMMON_CONFIG_ENTRY_SCHEMA ,
@@ -93,12 +94,30 @@ async def async_setup_entry(
9394 )
9495
9596
96- class StateImageEntity (TemplateEntity , ImageEntity ):
97+ class AbstractTemplateImage (AbstractTemplateEntity , ImageEntity ):
98+ """Representation of a template image features."""
99+
100+ _entity_id_format = ENTITY_ID_FORMAT
101+ _attr_image_url : str | None = None
102+
103+ # The super init is not called because TemplateEntity and TriggerEntity will call AbstractTemplateEntity.__init__.
104+ # This ensures that the __init__ on AbstractTemplateEntity is not called twice.
105+ def __init__ (self , hass : HomeAssistant , config : dict [str , Any ]) -> None : # pylint: disable=super-init-not-called
106+ """Initialize the features."""
107+ ImageEntity .__init__ (self , hass , config [CONF_VERIFY_SSL ])
108+ self ._url_template = config [CONF_URL ]
109+ self ._has_picture_template = CONF_PICTURE in config
110+
111+ def _handle_state (self , result : Any ) -> None :
112+ self ._attr_image_last_updated = dt_util .utcnow ()
113+ self ._cached_image = None
114+ self ._attr_image_url = result
115+
116+
117+ class StateImageEntity (TemplateEntity , AbstractTemplateImage ):
97118 """Representation of a template image."""
98119
99120 _attr_should_poll = False
100- _attr_image_url : str | None = None
101- _entity_id_format = ENTITY_ID_FORMAT
102121
103122 def __init__ (
104123 self ,
@@ -108,13 +127,12 @@ def __init__(
108127 ) -> None :
109128 """Initialize the image."""
110129 TemplateEntity .__init__ (self , hass , config , unique_id )
111- ImageEntity .__init__ (self , hass , config [CONF_VERIFY_SSL ])
112- self ._url_template = config [CONF_URL ]
130+ AbstractTemplateImage .__init__ (self , hass , config )
113131
114132 @property
115133 def entity_picture (self ) -> str | None :
116134 """Return entity picture."""
117- if self ._entity_picture_template :
135+ if self ._has_picture_template :
118136 return TemplateEntity .entity_picture .__get__ (self )
119137 # mypy doesn't know about fget: https://github.com/python/mypy/issues/6185
120138 return ImageEntity .entity_picture .fget (self ) # type: ignore[attr-defined]
@@ -124,9 +142,7 @@ def _update_url(self, result):
124142 if isinstance (result , TemplateError ):
125143 self ._attr_image_url = None
126144 return
127- self ._attr_image_last_updated = dt_util .utcnow ()
128- self ._cached_image = None
129- self ._attr_image_url = result
145+ self ._handle_state (result )
130146
131147 @callback
132148 def _async_setup_templates (self ) -> None :
@@ -135,12 +151,9 @@ def _async_setup_templates(self) -> None:
135151 super ()._async_setup_templates ()
136152
137153
138- class TriggerImageEntity (TriggerEntity , ImageEntity ):
154+ class TriggerImageEntity (TriggerEntity , AbstractTemplateImage ):
139155 """Image entity based on trigger data."""
140156
141- _attr_image_url : str | None = None
142- _entity_id_format = ENTITY_ID_FORMAT
143-
144157 domain = IMAGE_DOMAIN
145158 extra_template_keys = (CONF_URL ,)
146159
@@ -152,20 +165,18 @@ def __init__(
152165 ) -> None :
153166 """Initialize the entity."""
154167 TriggerEntity .__init__ (self , hass , coordinator , config )
155- ImageEntity .__init__ (self , hass , config [ CONF_VERIFY_SSL ] )
168+ AbstractTemplateImage .__init__ (self , hass , config )
156169
157170 @property
158171 def entity_picture (self ) -> str | None :
159172 """Return entity picture."""
173+ if self ._has_picture_template :
174+ return TriggerEntity .entity_picture .__get__ (self )
160175 # mypy doesn't know about fget: https://github.com/python/mypy/issues/6185
161- if CONF_PICTURE in self ._config :
162- return TriggerEntity .entity_picture .fget (self ) # type: ignore[attr-defined]
163176 return ImageEntity .entity_picture .fget (self ) # type: ignore[attr-defined]
164177
165178 @callback
166179 def _process_data (self ) -> None :
167180 """Process new data."""
168181 super ()._process_data ()
169- self ._attr_image_last_updated = dt_util .utcnow ()
170- self ._cached_image = None
171- self ._attr_image_url = self ._rendered .get (CONF_URL )
182+ self ._handle_state (self ._rendered .get (CONF_URL ))
0 commit comments