Skip to content

Commit ce523fc

Browse files
authored
Expose method to set last activated on scene (home-assistant#146884)
1 parent 5bb96f7 commit ce523fc

File tree

1 file changed

+30
-11
lines changed

1 file changed

+30
-11
lines changed

homeassistant/components/scene/__init__.py

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,16 @@
1212
from homeassistant.components.light import ATTR_TRANSITION
1313
from homeassistant.config_entries import ConfigEntry
1414
from homeassistant.const import CONF_PLATFORM, SERVICE_TURN_ON, STATE_UNAVAILABLE
15-
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant
15+
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant, callback
1616
from homeassistant.helpers.entity_component import EntityComponent
1717
from homeassistant.helpers.restore_state import RestoreEntity
1818
from homeassistant.helpers.typing import ConfigType
1919
from homeassistant.util import dt as dt_util
20+
from homeassistant.util.async_ import run_callback_threadsafe
2021
from homeassistant.util.hass_dict import HassKey
2122

2223
DOMAIN: Final = "scene"
23-
DATA_COMPONENT: HassKey[EntityComponent[Scene]] = HassKey(DOMAIN)
24+
DATA_COMPONENT: HassKey[EntityComponent[BaseScene]] = HassKey(DOMAIN)
2425
STATES: Final = "states"
2526

2627

@@ -62,7 +63,7 @@ def _platform_validator(config: dict[str, Any]) -> dict[str, Any]:
6263

6364
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
6465
"""Set up the scenes."""
65-
component = hass.data[DATA_COMPONENT] = EntityComponent[Scene](
66+
component = hass.data[DATA_COMPONENT] = EntityComponent[BaseScene](
6667
logging.getLogger(__name__), DOMAIN, hass
6768
)
6869

@@ -93,8 +94,8 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
9394
return await hass.data[DATA_COMPONENT].async_unload_entry(entry)
9495

9596

96-
class Scene(RestoreEntity):
97-
"""A scene is a group of entities and the states we want them to be."""
97+
class BaseScene(RestoreEntity):
98+
"""Base type for scenes."""
9899

99100
_attr_should_poll = False
100101
__last_activated: str | None = None
@@ -108,14 +109,14 @@ def state(self) -> str | None:
108109
return self.__last_activated
109110

110111
@final
111-
async def _async_activate(self, **kwargs: Any) -> None:
112-
"""Activate scene.
112+
def _record_activation(self) -> None:
113+
run_callback_threadsafe(self.hass.loop, self._async_record_activation).result()
113114

114-
Should not be overridden, handle setting last press timestamp.
115-
"""
115+
@final
116+
@callback
117+
def _async_record_activation(self) -> None:
118+
"""Update the activation timestamp."""
116119
self.__last_activated = dt_util.utcnow().isoformat()
117-
self.async_write_ha_state()
118-
await self.async_activate(**kwargs)
119120

120121
async def async_internal_added_to_hass(self) -> None:
121122
"""Call when the scene is added to hass."""
@@ -128,6 +129,10 @@ async def async_internal_added_to_hass(self) -> None:
128129
):
129130
self.__last_activated = state.state
130131

132+
async def _async_activate(self, **kwargs: Any) -> None:
133+
"""Activate scene."""
134+
raise NotImplementedError
135+
131136
def activate(self, **kwargs: Any) -> None:
132137
"""Activate scene. Try to get entities into requested state."""
133138
raise NotImplementedError
@@ -137,3 +142,17 @@ async def async_activate(self, **kwargs: Any) -> None:
137142
task = self.hass.async_add_executor_job(ft.partial(self.activate, **kwargs))
138143
if task:
139144
await task
145+
146+
147+
class Scene(BaseScene):
148+
"""A scene is a group of entities and the states we want them to be."""
149+
150+
@final
151+
async def _async_activate(self, **kwargs: Any) -> None:
152+
"""Activate scene.
153+
154+
Should not be overridden, handle setting last press timestamp.
155+
"""
156+
self._async_record_activation()
157+
self.async_write_ha_state()
158+
await self.async_activate(**kwargs)

0 commit comments

Comments
 (0)