Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
5ee6a21
Fix Flume sensor units and device classes (#169013)
shbatm Apr 24, 2026
c9d8257
Return None for Velux cover position when unknown (#168566)
mnaggatz Apr 24, 2026
a19aebe
Keep add-on update entity in progress across post-install refresh (#1…
agners Apr 24, 2026
aad93fd
Add tests asserting condition features (#168881)
emontnemery Apr 24, 2026
599fe25
Fix feedreader tests broken by Python 3.14.3 asyncio changes (#169080)
mib1185 Apr 24, 2026
e422c08
Support media player for Shelly Wall Display (#168494)
bieniu Apr 24, 2026
a53d3ea
Update frontend to 20260325.8 (#169076)
bramkragten Apr 24, 2026
8b2afb4
Add a dynamic sensitivity slider for Matter sensors (#167710)
wardmatter Apr 24, 2026
9369a5d
Slow down Tractive API polling to avoid 429 too many requests (#169057)
bieniu Apr 24, 2026
4d8acfa
Disable knx tests broken by Python 3.14.3 asyncio changes (#169079)
justanotherariel Apr 24, 2026
4f5d0a7
Disable plex tests broken by Python 3.14.3 asyncio changes (#169069)
justanotherariel Apr 24, 2026
6fe1862
Disable dsmr tests broken by Python 3.14.3 asyncio changes (#169064)
justanotherariel Apr 24, 2026
446d89a
Disable rflink tests broken by Python 3.14.3 asyncio changes (#169074)
justanotherariel Apr 24, 2026
ca70abe
Refactor button platform to use indevolt-api 1.4.2 (#169063)
Xirt Apr 24, 2026
1e0dc86
Use new UPTIME sensor class for Shelly (#169088)
chemelli74 Apr 24, 2026
822b97d
Upgrade unifi_access quality scale to platinum (#168204)
RaHehl Apr 24, 2026
2deb364
Reinforce Python 3.14 exceptions Agent instructions (#169089)
abmantis Apr 24, 2026
99185bf
Bump israel-rail-api to 0.1.5 (#169094)
mikomgk Apr 24, 2026
e7aa672
Register MAC address connections on Synology DSM hub device (#169085)
tomwilkie Apr 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ This repository contains the core of Home Assistant, a Python 3 based home autom

## Python Syntax Notes

- Python 3.14 explicitly allows `except TypeA, TypeB:` without parentheses.
- Python 3.14 explicitly allows `except TypeA, TypeB:` without parentheses. Never flag this as an issue since Home Assistant officially supports Python 3.14.

## Testing

Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This repository contains the core of Home Assistant, a Python 3 based home autom

## Python Syntax Notes

- Python 3.14 explicitly allows `except TypeA, TypeB:` without parentheses.
- Python 3.14 explicitly allows `except TypeA, TypeB:` without parentheses. Never flag this as an issue since Home Assistant officially supports Python 3.14.

## Testing

Expand Down
11 changes: 7 additions & 4 deletions homeassistant/components/flume/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.const import UnitOfVolume
from homeassistant.const import UnitOfVolume, UnitOfVolumeFlowRate
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.typing import StateType
Expand All @@ -34,7 +34,8 @@
key="current_interval",
translation_key="current_interval",
suggested_display_precision=2,
native_unit_of_measurement=f"{UnitOfVolume.GALLONS}/m",
native_unit_of_measurement=UnitOfVolumeFlowRate.GALLONS_PER_MINUTE,
device_class=SensorDeviceClass.VOLUME_FLOW_RATE,
state_class=SensorStateClass.MEASUREMENT,
),
SensorEntityDescription(
Expand Down Expand Up @@ -65,14 +66,16 @@
key="last_60_min",
translation_key="last_60_min",
suggested_display_precision=2,
native_unit_of_measurement=f"{UnitOfVolume.GALLONS}/h",
native_unit_of_measurement=UnitOfVolumeFlowRate.GALLONS_PER_HOUR,
device_class=SensorDeviceClass.VOLUME_FLOW_RATE,
state_class=SensorStateClass.MEASUREMENT,
),
SensorEntityDescription(
key="last_24_hrs",
translation_key="last_24_hrs",
suggested_display_precision=2,
native_unit_of_measurement=f"{UnitOfVolume.GALLONS}/d",
native_unit_of_measurement=UnitOfVolumeFlowRate.GALLONS_PER_DAY,
device_class=SensorDeviceClass.VOLUME_FLOW_RATE,
state_class=SensorStateClass.MEASUREMENT,
),
SensorEntityDescription(
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/frontend/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@
"integration_type": "system",
"preview_features": { "winter_mode": {} },
"quality_scale": "internal",
"requirements": ["home-assistant-frontend==20260325.7"]
"requirements": ["home-assistant-frontend==20260325.8"]
}
49 changes: 45 additions & 4 deletions homeassistant/components/hassio/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,27 @@ async def async_setup_entry(


class SupervisorAddonUpdateEntity(HassioAddonEntity, UpdateEntity):
"""Update entity to handle updates for the Supervisor add-ons."""
"""Update entity to handle updates for the Supervisor add-ons.

The ``addon_manager_update`` job emits a ``done=True`` WS event as soon as
Supervisor finishes the container work, a few milliseconds before the
``/store/addons/<slug>/update`` HTTP call returns. If we clear
``_attr_in_progress`` on that event while the coordinator data still
carries the pre-update version, the UI briefly flips back to
"Update available" before ``async_install`` can refresh. ``_update_ongoing``
survives both the WS done event and the base ``UpdateEntity`` reset, so
the installing state remains until the coordinator confirms a new
``installed_version``.
"""

_attr_supported_features = (
UpdateEntityFeature.INSTALL
| UpdateEntityFeature.BACKUP
| UpdateEntityFeature.RELEASE_NOTES
| UpdateEntityFeature.PROGRESS
)
_update_ongoing: bool = False
_version_before_update: str | None = None

@property
def _addon_data(self) -> dict:
Expand All @@ -121,6 +134,13 @@ def installed_version(self) -> str | None:
"""Version installed and in use."""
return self._addon_data[ATTR_VERSION]

@property
def in_progress(self) -> bool | None:
"""Return combined progress from the update job and refresh phase."""
if self._update_ongoing:
return True
return self._attr_in_progress

@property
def entity_picture(self) -> str | None:
"""Return the icon of the add-on if any."""
Expand Down Expand Up @@ -154,13 +174,34 @@ async def async_install(
**kwargs: Any,
) -> None:
"""Install an update."""
self._version_before_update = self.installed_version
self._update_ongoing = True
self._attr_in_progress = True
self.async_write_ha_state()
await update_addon(
self.hass, self._addon_slug, backup, self.title, self.installed_version
)
try:
await update_addon(
self.hass, self._addon_slug, backup, self.title, self.installed_version
)
except HomeAssistantError:
self._update_ongoing = False
self._version_before_update = None
self._attr_in_progress = False
self._attr_update_percentage = None
self.async_write_ha_state()
raise
await self.coordinator.async_refresh()

@callback
def _handle_coordinator_update(self) -> None:
"""Clear the ongoing flag once the installed version has changed."""
if (
self._update_ongoing
and self.installed_version != self._version_before_update
):
self._update_ongoing = False
self._version_before_update = None
super()._handle_coordinator_update()

@callback
def _update_job_changed(self, job: Job) -> None:
"""Process update for this entity's update job."""
Expand Down
5 changes: 3 additions & 2 deletions homeassistant/components/indevolt/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from dataclasses import dataclass, field
from typing import Final

from indevolt_api import IndevoltRealtimeAction

from homeassistant.components.button import ButtonEntity, ButtonEntityDescription
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
Expand Down Expand Up @@ -66,5 +68,4 @@ def __init__(

async def async_press(self) -> None:
"""Handle the button press."""

await self.coordinator.async_execute_realtime_action([0, 0, 0])
await self.coordinator.async_realtime_action(IndevoltRealtimeAction.STOP)
3 changes: 1 addition & 2 deletions homeassistant/components/indevolt/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
ENERGY_MODE_WRITE_KEY: Final = "47005"
PORTABLE_MODE: Final = 0

# API write key and value for real-time control mode
REALTIME_ACTION_KEY: Final = "47015"
# Value for real-time control mode
REALTIME_ACTION_MODE: Final = 4

# API key fields
Expand Down
20 changes: 8 additions & 12 deletions homeassistant/components/indevolt/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from typing import Any, Final

from aiohttp import ClientError
from indevolt_api import IndevoltAPI, TimeOutException
from indevolt_api import IndevoltAPI, IndevoltRealtimeAction, TimeOutException

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_MODEL
Expand All @@ -24,7 +24,6 @@
ENERGY_MODE_READ_KEY,
ENERGY_MODE_WRITE_KEY,
PORTABLE_MODE,
REALTIME_ACTION_KEY,
REALTIME_ACTION_MODE,
SENSOR_KEYS,
)
Expand Down Expand Up @@ -146,19 +145,16 @@ async def async_switch_energy_mode(
if refresh:
await self.async_request_refresh()

async def async_execute_realtime_action(self, action: list[int]) -> None:
async def async_realtime_action(
self,
action_code: IndevoltRealtimeAction,
) -> None:
"""Switch mode, execute action, and refresh for real-time control."""

await self.async_switch_energy_mode(REALTIME_ACTION_MODE, refresh=False)

try:
success = await self.async_push_data(REALTIME_ACTION_KEY, action)

except (DeviceTimeoutError, DeviceConnectionError) as err:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="failed_to_execute_realtime_action",
) from err
match action_code:
case IndevoltRealtimeAction.STOP:
success = await self.api.stop()

if not success:
raise HomeAssistantError(
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/israel_rail/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
"integration_type": "service",
"iot_class": "cloud_polling",
"loggers": ["israelrailapi"],
"requirements": ["israel-rail-api==0.1.4"]
"requirements": ["israel-rail-api==0.1.5"]
}
25 changes: 25 additions & 0 deletions homeassistant/components/matter/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,31 @@ def _update_from_device(self) -> None:
featuremap_contains=clusters.OccupancySensing.Bitmaps.Feature.kPassiveInfrared,
allow_multi=True,
),
MatterDiscoverySchema(
platform=Platform.NUMBER,
entity_description=MatterRangeNumberEntityDescription(
key="BooleanStateConfigurationCurrentSensitivityLevel",
entity_category=EntityCategory.CONFIG,
translation_key="sensitivity_level",
native_min_value=1,
native_step=1,
device_to_ha=lambda x: x + 1,
ha_to_device=lambda x: int(x) - 1,
max_attribute=(
clusters.BooleanStateConfiguration.Attributes.SupportedSensitivityLevels
),
mode=NumberMode.SLIDER,
),
entity_class=MatterRangeNumber,
required_attributes=(
clusters.BooleanStateConfiguration.Attributes.CurrentSensitivityLevel,
clusters.BooleanStateConfiguration.Attributes.SupportedSensitivityLevels,
),
featuremap_contains=(
clusters.BooleanStateConfiguration.Bitmaps.Feature.kSensitivityLevel
),
allow_multi=True,
),
MatterDiscoverySchema(
platform=Platform.NUMBER,
entity_description=MatterNumberEntityDescription(
Expand Down
9 changes: 9 additions & 0 deletions homeassistant/components/matter/select.py
Original file line number Diff line number Diff line change
Expand Up @@ -559,11 +559,15 @@ def _update_from_device(self) -> None:
clusters.PumpConfigurationAndControl.Attributes.OperationMode,
),
),
# Keep the legacy vendor-specific select entities until HA 2026.11.0,
# so existing users can migrate before we remove them in favor of the
# generic number slider.
MatterDiscoverySchema(
platform=Platform.SELECT,
entity_description=MatterSelectEntityDescription(
key="AqaraBooleanStateConfigurationCurrentSensitivityLevel",
entity_category=EntityCategory.CONFIG,
entity_registry_enabled_default=False,
translation_key="sensitivity_level",
options=["10 mm", "20 mm", "30 mm"],
device_to_ha={
Expand All @@ -583,12 +587,14 @@ def _update_from_device(self) -> None:
),
vendor_id=(4447,),
product_id=(8194,),
allow_multi=True,
),
MatterDiscoverySchema(
platform=Platform.SELECT,
entity_description=MatterSelectEntityDescription(
key="AqaraOccupancySensorBooleanStateConfigurationCurrentSensitivityLevel",
entity_category=EntityCategory.CONFIG,
entity_registry_enabled_default=False,
translation_key="sensitivity_level",
options=["low", "standard", "high"],
device_to_ha={
Expand All @@ -611,12 +617,14 @@ def _update_from_device(self) -> None:
8197,
8195,
),
allow_multi=True,
),
MatterDiscoverySchema(
platform=Platform.SELECT,
entity_description=MatterSelectEntityDescription(
key="HeimanOccupancySensorBooleanStateConfigurationCurrentSensitivityLevel",
entity_category=EntityCategory.CONFIG,
entity_registry_enabled_default=False,
translation_key="sensitivity_level",
options=["low", "standard", "high"],
device_to_ha={
Expand All @@ -636,6 +644,7 @@ def _update_from_device(self) -> None:
),
vendor_id=(4619,),
product_id=(4097,),
allow_multi=True,
),
MatterDiscoverySchema(
platform=Platform.SELECT,
Expand Down
3 changes: 3 additions & 0 deletions homeassistant/components/matter/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,9 @@
"pump_setpoint": {
"name": "Setpoint"
},
"sensitivity_level": {
"name": "Sensitivity"
},
"speaker_setpoint": {
"name": "Volume"
},
Expand Down
1 change: 1 addition & 0 deletions homeassistant/components/shelly/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
Platform.COVER,
Platform.EVENT,
Platform.LIGHT,
Platform.MEDIA_PLAYER,
Platform.NUMBER,
Platform.SELECT,
Platform.SENSOR,
Expand Down
2 changes: 0 additions & 2 deletions homeassistant/components/shelly/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,6 @@
BLOCK_WRONG_SLEEP_PERIOD = 21600
BLOCK_EXPECTED_SLEEP_PERIOD = 43200

UPTIME_DEVIATION: Final = 60

# Time to wait before reloading entry upon device config change
ENTRY_RELOAD_COOLDOWN = 60

Expand Down
Loading
Loading