Skip to main content

New entity feature flags in FanEntity

· One min read

As of Home Assistant Core 2024.8, we have added two new flags to FanEntityFeature: TURN_ON, TURN_OFF.

Integrations implementing the turn_on service call need to set the TURN_ON feature flag. Integrations implementing the turn_off service call need to set the TURN_OFF feature flag.

There will be a 6-month deprecation period (2025.2) during which FanEntity will set these on behalf of the integrations implementing the respective methods. From 2025.2, integrations will be unable to use the respective methods if entity features have not been set accordingly.

Implementing the methods without setting the respective feature flag, will create a warning log entry guiding the user to create an issue for the integration.

Integrations should set the attribute _enable_turn_on_off_backwards_compatibility in your FanEntity subclass instance to False once it has been migrated into using or not using the new feature flags. This will stop the automatic setting of the new feature flags during the deprecation period, and should be removed once deprecation has ended.

model_id added to DeviceInfo

· One min read

Starting from 2024.8, you can now add a model identifier to the DeviceInfo class. This identifier can be used to identify the device model in integrations and the frontend.

For example, the Philips Hue ambiance spot was previously listed as "Hue ambiance spot (LTG002)". This can now be split up, where the model is "Hue ambiance spot" and the model_id is "LTG002".

Services are now actions

· 2 min read

The term "Services" has been a source of confusion for many users, as it is not immediately clear what it refers to; it could be a web or STT service, but in the context of Home Assistant, it means something entirely different (service calls).

In Home Assistant 2024.8, "Services" (as in service calls) will be renamed to "Actions". This change is part of our ongoing effort to make Home Assistant more user-friendly and easier for new users to understand. The term fits in with the UI changes we have been implementing over the past months (call services no longer exist in our automations and script editors). Effectively, one is performing actions in one's automations.

This change will be reflected in the Home Assistant UI, documentation, and other places where the term "Services" is used. For example, the "Services" tab in the Developer Tools will be renamed to "Actions".

For developers, there is no need to worry about this change. In the developer documentation, we will update all references to "services" to "service actions", as we have different types of actions in our backend (for example, device actions). The underlying functionality will remain the same, and the transition is seamless.

This is, just like the end-user change, a terminology change only.

New HVACAction DEFROSTING

· One min read

The ClimateEntity has an hvac_action property, which describes what the climate entity is currently doing (which is not the same as its mode).

We have added DEFROSTING as a possible HVACAction to represent when an entity is currently defrosting.

Defrosting is when the system runs in reverse for some time to melt down accumulated ice. It occurs typically in colder environments and should not be mixed with, for example, cars that are defrosting by heating their windows.

from homeassistant.components.climate.const import HVACAction

class MyClimateEntity(ClimateEntity):
"""Implementation of my climate entity."""

def hvac_action(self) -> HVACAction | None:
"""Return the current running hvac operation if supported."""
return HVACAction.DEFROSTING

More details can be found in the climate entity documentation

Background for the original change is in architecture discussion #1090.

Excluding all state attributes from recording using MATCH_ALL

· One min read

The way how state attributes are excluded from the recording was previously changed in September 2023.

The previous implementation was limited as there was no way to handle dynamic attributes or any easy way to simply exclude all attributes instead of listing them individually.

It is now possible within an integration to tell recording to not record any attribute by using the MATCH_ALL constant, which will automatically remove all attributes from recording except device_class, state_class, unit_of_measurement, and friendly_name.

from homeassistant.const import MATCH_ALL

class ExampleEntity(Entity):
"""Implementation of an entity."""

_unrecorded_attributes = frozenset({MATCH_ALL})

More details can be found in the entity documentation.

Background for the original change is in architecture discussion #964.

Making http path registration async safe with `async_register_static_paths`

· One min read

hass.http.register_static_path is deprecated because it does blocking I/O in the event loop, instead call await hass.http.async_register_static_paths([StaticPathConfig(url_path, path, cache_headers)])

The arguments to async_register_static_paths are the same as register_static_path except they are wrapped in the StaticPathConfig dataclass and an Iterable of them is accepted to allow registering multiple paths at once to avoid multiple executor jobs.

For example, if your integration called hass.http.register_static_path("/integrations/photos", "/config/photos", True), it should now call await hass.http.async_register_static_paths([StaticPathConfig("/integrations/photos", "/config/photos", True)])

The StaticPathConfig dataclass should be imported from homeassistant.components.http

hass.http.register_static_path will be removed in 2025.7

Example

from pathlib import Path
from homeassistant.components.http import StaticPathConfig

should_cache = False
files_path = Path(__file__).parent / "static"
files2_path = Path(__file__).parent / "static2"

await hass.http.async_register_static_paths([
StaticPathConfig("/api/my_integration/static", str(files_path), should_cache),
StaticPathConfig("/api/my_integration/static2", str(files2_path), should_cache)
])

Forwarding setup to config entry platforms

· One min read

Calling hass.config_entries.async_forward_entry_setup is deprecated and will be removed in Home Assistant 2025.6. Instead, await hass.config_entries.async_forward_entry_setups as it can load multiple platforms at once and is more efficient since it does not require a separate import executor job for each platform.

hass.config_entries.async_forward_entry_setups must always be awaited if it's called while the config entry is being set up to ensure that it finishes before the config entry setup is complete. For more details, review this blog post.

Alarm Control Panel Entity code validation

· One min read

The AlarmControlPanelEntity is now enforcing validation of code for alarm control panel entities, which set code_arm_required to True (default behavior). Service calls fail if no code is provided when a code is required.

Previously this was entirely optional, and a user could skip code entry regardless of it was needed by the integration or not (and as such each integration needed to implement its own check).

As the default behavior is that code is required, custom integrations that don't require a code input need to set code_arm_required to False or the user will always have to input a code regardless of if it's needed by the service calls.

Exposing Home Assistant API to LLMs

· One min read

Since we introduced LLMs in Home Assistant as part of Year of the Voice, we have received the request to allow enabling LLMs to interact with Home Assistant. This is now possible by exposing a Home Assistant API to LLMs.

Home Assistant will come with a built-in Assist API, which follows the capabilities and exposed entities that are also accessible to the built-in conversation agent.

Integrations that interact with LLMs should update their integration to support LLM APIs.

Custom integration authors can create their own LLM APIs to offer LLMs more advanced access to Home Assistant.

See the LLM API documentation for more information and this example pull request on how to integrate the LLM API in your integration.

Handling time zones without blocking the event loop

· One min read

Constructing ZoneInfo objects may do blocking I/O to load the zone info from disk if the timezone passed is not in the cache.

dt_util.async_get_time_zone is now available to replace dt_util.get_time_zone to fetch a time zone in the event loop which is async safe and will not do blocking I/O in the event loop.

hass.config.set_time_zone is deprecated and replaced with hass.config.async_set_time_zone. hass.config.set_time_zone will be removed in 2025.6. Setting the time zone only affects tests, as no integration should be calling this function in production.

Examining dt_util.DEFAULT_TIME_ZONE directly is deprecated and dt_util.get_default_time_zone() should be used instead.

If your integration needs to construct ZoneInfo objects in the event loop, it is recommended to use the aiozoneinfo library.