Skip to main content

Handling open file limit in add-ons since OS 16

· 2 min read

With the release of Home Assistant OS 16, the default limit for open file descriptors in Docker containers (and, by extension, all add-ons and the processes within them) has changed. Home Assistant OS now uses the default values provided by Systemd: a soft limit of 1024 and a hard limit of 524288 open files.

This is a change from previous OS versions, where the limit was set to "infinity" (effectively a value over 1 billion) — also introduced as an upstream change — since Home Assistant OS 10. The new limits are consistent with common practices on modern Linux systems and follow changes gradually being adopted across other Linux distributions.

For more details on these limits and best practices, see Lennart Poettering's explanation on File Descriptor Limits. In summary, applications that require more than the default soft limit of 1024 file descriptors should explicitly raise their own limit at startup, up to the hard limit imposed by the system (in our case, 524288). This approach ensures each application only requests the resources it needs and avoids system-wide high limits that may lead to unexpected resource exhaustion.

What does this mean for add-on developers?

  • If your application running as an add-on needs to open more than 1024 files (sockets, pipes, etc.), you should adjust the limit yourself, for example using ulimit -Sn <value>, as long as <value> does not exceed the hard limit (which can be checked with ulimit -Hn).
  • Most add-ons will likely not be affected by this change, but some — such as those handling many network connections or accessing numerous files (e.g., databases or file sharing applications) — may need to adapt their startup routines.

What happens if the limit is too low?

If an add-on or its application requires more file descriptors than the default soft limit (1024) and does not raise the limit itself, it may fail to open additional files, sockets, or network connections once the limit is reached. This typically results in errors such as "Too many open files" or "No file descriptors available" (EMFILE), failing network connections, or malfunctioning services.

If you have any questions or encounter issues, please refer to this GitHub discussion, which also contains more details and background information about this topic.

Vacuum battery properties are deprecated

· One min read

As of Home Assistant Core 2025.8, the two properties for battery in StateVacuumEntity, battery_level and battery_icon, have been deprecated.

The battery_level and battery_icon properties should be replaced by a separate sensor with the battery sensor device class and optionally a customized icon if the default icon of the battery sensor device class isn't wanted. Optionally consider to also provide a binary sensor with the charging device class if it's currently charging or not.

There is a one-year deprecation period, and the two battery properties will stop working from 2026.8 to ensure all custom integration authors have time to adjust.

More details can be found in the architectural decision.

Sensor device classes now have default display precision

· One min read

If a numeric sensor doesn't have a suggested display precision set by its integration, Home Assistant will now use a default display precision based on the sensor's device class.

New device classes should be added to UNITS_PRECISION in homeassistant/components/sensor/const.py, along with the proper unit and the desired default display precision. See the docstring of that constant for more details on how to choose the right unit and precision.

The rounding that was previously applied to the sensor state when a unit conversion was happening is now removed, and the sensor state contains the full raw value.

It is still recommended that integrations set the suggested_display_precision on their sensors. This change is a fallback mechanism to ensure a consistent experience across all numeric sensors.

For more details check the implementation pull request and the Sensor entity documentation.

Icon translations now support ranges

· One min read

Icon translations now support defining icons based on numeric ranges. This means integration authors can define icons that change based on numeric values without implementing custom logic in their code.

Previously, icon translations only supported state-based icons, where specific states would map to specific icons. While this works well for discrete states like "on"/"off", it required custom code to handle numeric values like battery levels or signal strength indicators.

Range-based icons are defined in the icons.json file:

{
"entity": {
"sensor": {
"battery_level": {
"default": "mdi:battery",
"range": {
"0": "mdi:battery-outline",
"10": "mdi:battery-10",
"20": "mdi:battery-20",
"30": "mdi:battery-30",
"40": "mdi:battery-40",
"50": "mdi:battery-50",
"60": "mdi:battery-60",
"70": "mdi:battery-70",
"80": "mdi:battery-80",
"90": "mdi:battery-90",
"100": "mdi:battery"
}
}
}
}
}

The system selects the icon associated with the highest range value that's less than or equal to the entity's current value. For example:

  • A value of 15 will show the mdi:battery-10 icon
  • A value of 45 will show the mdi:battery-40 icon
  • A value of 100 will show the mdi:battery icon

For implementation details, see the icon translations documentation.

Device tracker TrackerEntity location accuracy attribute type change

· One min read

The type of location_accuracy attribute (short hand _attr_location_accuracy) of the TrackerEntity class of the device_tracker entity component has been changed from int to float.

Type conversions in case the source value is a float are no longer needed.

Example

class ExampleTrackerEntity(TrackerEntity):
"""Test tracker entity."""

_attr_location_accuracy: float = 2.5

@cached_property
def location_accuracy(self) -> float:
"""Return the location accuracy of the device.

Value in meters.
"""
return self._attr_location_accuracy

Searching in media players

· One min read

Media players can now allow users to search through the media, by adding MediaEntityFeature.SEARCH_MEDIA and implementing async_search_media. The users can filter the search result by a search query and a list of MediaClasses that the returned results should have. For more info, see the updated documentation.

UnitSystem dataclass is now frozen

· One min read

UnitSystem class is changed to a frozen data class, and all instances derived from it are now frozen.

The following unit systems that derived from the UnitSystem class are now frozen:

  • METRIC_SYSTEM
  • US_CUSTOMARY_SYSTEM

The reason for this change is that Unit systems are constants that should not be modified. An integration that modifies these constants can break unit conversions and create undesired output for other components of Home Assistant.

With a frozen data class an attempt to modify the UnitSystem constant will fail:

dataclasses.FrozenInstanceError: cannot assign to field 'temperature_unit'

This change was introduced in the home assistant core PR #140954.

Changes to ConfigSubentryFlow

· One min read

ConfigSubentryFlow._reconfigure_entry_id has been renamed to ConfigSubentryFlow._entry_id and ConfigSubentryFlow._get_reconfigure_entry has been renamed to ConfigSubentryFlow._get_entry.

The reason for the change is that both sub entry user flows and subentry reconfigure flows need access to parent config entry, e.g. getting options, data, etc.

Custom integrations which call either of the renamed methods need to update their implementations.

The change is introduced in the home assistant core PR #141017.

Media player toggle action changed

· One min read

The implementation of the toggle action service has been adjusted in the media player base class. The media player will now be turned on if it is in the states off or standby; in all other states, it will be turned off.

Before this change, the media player would also be turned on if it was in state idle. This was not in line with the meaning of the idle state, as it is counted as a state where the device is already turned on.

Custom integrations which have overridden the async_toggle may need to update their implementations.

The change is introduced in the home assistant core PR #78192.