Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
97d9c23
Bump yoto-api to 3.1.5 (#172753)
piitaya Jun 1, 2026
c22f10b
Run Overkiz unique ID migration only once via config entry version (#…
iMicknl Jun 1, 2026
ce46be1
Add support for Thread Integration to Display Icons for Yeelight TBRs…
wardmatter Jun 1, 2026
0abc9b7
Ignore Beacons security policy flag in Thread dataset comparison (#17…
balloob Jun 1, 2026
480a8d5
upb: Move to SerialPortSelector (#170053)
DaAwesomeP Jun 1, 2026
e45f64b
Add media browser to Yoto (#172325)
piitaya Jun 1, 2026
8e19fd2
Add Thread and Wi-Fi RSSI diagnostic sensors to Matter integration (#…
markvp Jun 1, 2026
eb3fd52
Add actions permission to delete stalebot state (#172704)
silamon Jun 1, 2026
04442bb
Use proper user-agent to fetch feeds (#172655)
mib1185 Jun 1, 2026
018e42e
Add custom themes to Cloud support package (#172708)
mellowism Jun 1, 2026
c901160
Bump aioaquarite to 0.5.1 (#172754)
fdebrus Jun 1, 2026
25f18c6
media_player platform fixes for Alexa Devices (#172611)
jamesonuk Jun 1, 2026
7fb475a
Add cover platform to Fluss (#169908)
Marcello17 Jun 1, 2026
d7219aa
Fix binary sensor defaults for Indevolt (#172714)
Xirt Jun 1, 2026
be2aaf9
Support Yardian YC models (#172347)
aeon-matrix Jun 1, 2026
cad177c
Rename constant in reload helper test (#172711)
epenet Jun 1, 2026
1865c16
Explain why a LED BLE device could not be found (#172764)
bdraco Jun 1, 2026
063fa8d
Explain why an INKBIRD device could not be found (#172762)
bdraco Jun 1, 2026
a65503f
Explain why an Airthings BLE device could not be found (#172758)
bdraco Jun 1, 2026
0f01148
Explain why a Yale Access Bluetooth device could not be found (#172761)
bdraco Jun 1, 2026
155cb38
Fix get_play_status function call in frontier silicon (#172705)
wlcrs Jun 1, 2026
7e36d26
Filter stale replayed BLE advertisements in Matter BLE proxy (#172773)
Apollon77 Jun 1, 2026
b069bc2
Bump habluetooth to 6.8.1 (#172768)
bdraco Jun 1, 2026
01d3902
Refactor blebox integration to use DataUpdateCoordinator (#172533)
bkobus-bbx Jun 1, 2026
6a836bd
Add tests for Overkiz select platform (#171899)
iMicknl Jun 1, 2026
a19f304
Remove `battery_level` property from Tractive device tracker (#172756)
bieniu Jun 1, 2026
ec995a3
Fix ProxmoxVE missing unused token data (#172782)
CoMPaTech Jun 1, 2026
477756d
Add Helty Flow integration (#172736)
ebaschiera Jun 1, 2026
9c1cc55
Add OpenEVSE diagnostics (#171762)
firstof9 Jun 1, 2026
25ce817
Bump github/gh-aw-actions from 0.75.0 to 0.76.0 (#172777)
dependabot[bot] Jun 1, 2026
fb28825
Add tests for Overkiz siren platform (#171900)
iMicknl Jun 1, 2026
0272060
Bump dessant/lock-threads from 6.0.1 to 6.0.2 (#172776)
dependabot[bot] Jun 1, 2026
8ca4471
Cancel iCloud polling timer on config entry unload (#172793)
frenck Jun 1, 2026
2d8cebf
Bump frontend to 20260527.2 (#172759)
bramkragten Jun 1, 2026
2f03b7c
Explain why an eQ-3 Bluetooth device could not be found (#172770)
bdraco Jun 1, 2026
3664eb4
Explain why a Snooz device could not be found (#172780)
bdraco Jun 1, 2026
31fcbe7
Explain why an LD2410 BLE device could not be found (#172779)
bdraco Jun 1, 2026
f5819d4
Explain why a Husqvarna Automower BLE device could not be connected t…
bdraco Jun 1, 2026
71eefdc
Migrate async_migrate_entry test calls to async_setup in growatt_serv…
johanzander Jun 1, 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
14 changes: 7 additions & 7 deletions .github/workflows/check-requirements.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .github/workflows/lock.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
issues: write # To lock issues
pull-requests: write # To lock pull requests
steps:
- uses: dessant/lock-threads@851cffe46851ddd2051ea7147ebdc995113241c3 # v6.0.1
- uses: dessant/lock-threads@89ae32b08ed1a541efecbab17912962a5e38981c # v6.0.2
with:
github-token: ${{ github.token }}
issue-inactive-days: "30"
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/stale.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ jobs:
permissions:
issues: write # To label and close stale issues
pull-requests: write # To label and close stale PRs
actions: write # To delete stalebot state
steps:
# The 60 day stale policy for PRs
# Used for:
Expand Down Expand Up @@ -58,7 +59,7 @@ jobs:
# v3.2.0
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1
with:
app-id: ${{ secrets.ISSUE_TRIAGE_APP_ID }} # zizmor: ignore[secrets-outside-env]
client-id: ${{ secrets.ISSUE_TRIAGE_APP_ID }} # zizmor: ignore[secrets-outside-env]
private-key: ${{ secrets.ISSUE_TRIAGE_APP_PEM }} # zizmor: ignore[secrets-outside-env]

# The 90 day stale policy for issues
Expand Down
2 changes: 2 additions & 0 deletions CODEOWNERS

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 11 additions & 1 deletion homeassistant/components/airthings_ble/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from bleak_retry_connector import close_stale_connections_by_address

from homeassistant.components import bluetooth
from homeassistant.components.bluetooth import BluetoothReachabilityIntent
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
Expand Down Expand Up @@ -63,7 +64,16 @@ async def _async_setup(self) -> None:

if not ble_device:
raise ConfigEntryNotReady(
f"Could not find Airthings device with address {address}"
translation_domain=DOMAIN,
translation_key="device_not_found",
translation_placeholders={
"address": address,
"reason": bluetooth.async_address_reachability_diagnostics(
self.hass,
address.upper(),
BluetoothReachabilityIntent.CONNECTION,
),
},
)
self.ble_device = ble_device

Expand Down
5 changes: 5 additions & 0 deletions homeassistant/components/airthings_ble/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,10 @@
"name": "Radon longterm level"
}
}
},
"exceptions": {
"device_not_found": {
"message": "Could not find Airthings device with address {address}: {reason}"
}
}
}
21 changes: 20 additions & 1 deletion homeassistant/components/alexa_devices/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,26 @@ def vocal_records(self) -> dict[str, AmazonVocalRecord]:

async def sync_media_state(self) -> None:
"""Sync media state."""
await self.api.sync_media_state()
try:
await self.api.sync_media_state()
except CannotAuthenticate as err:
raise ConfigEntryAuthFailed(
translation_domain=DOMAIN,
translation_key="invalid_auth",
translation_placeholders={"error": repr(err)},
) from err
except (CannotConnect, TimeoutError) as err:
raise ConfigEntryNotReady(
translation_domain=DOMAIN,
translation_key="cannot_connect_with_error",
translation_placeholders={"error": repr(err)},
) from err
except (CannotRetrieveData, ValueError) as err:
raise ConfigEntryNotReady(
translation_domain=DOMAIN,
translation_key="cannot_retrieve_data_with_error",
translation_placeholders={"error": repr(err)},
) from err

async def media_state_event_handler(
self, media_state: dict[str, AmazonMediaState]
Expand Down
24 changes: 17 additions & 7 deletions homeassistant/components/alexa_devices/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,11 @@ def volume_level(self) -> float | None:
@property
def is_volume_muted(self) -> bool | None:
"""Return True if the volume is muted."""
if not self.volume_state:
if not self.volume_state or self.volume_state.volume is None:
return None
return self.volume_state.volume == 0
# is_muted is True when Alexa has muted the device
# volume == 0 is where we have muted by setting volume to 0
return self.volume_state.is_muted or self.volume_state.volume == 0

@property
def media_title(self) -> str | None:
Expand Down Expand Up @@ -259,12 +261,20 @@ async def async_mute_volume(self, mute: bool) -> None:
return
if mute:
self._prev_volume = self.volume_state.volume
target_volume = 0
else:
if self._prev_volume is None:
return
target_volume = self._prev_volume
await self.async_set_volume_level(0)
return

if self.volume_state.is_muted and self._prev_volume is None:
# is muted by Alexa which we can see but not control
# when muted this way, volume is still set
# changing volume will unmute
# if HA set volume to 0 then Alexa muted we just default to 30%
self._prev_volume = self.volume_state.volume or 30
if self._prev_volume is None:
return
target_volume = self._prev_volume
await self.async_set_volume_level(target_volume / 100)
self._prev_volume = None

@alexa_api_call
async def _send_media_command(self, command: AmazonMediaControls) -> None:
Expand Down
3 changes: 3 additions & 0 deletions homeassistant/components/alexa_devices/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@
},
"invalid_sound_value": {
"message": "Invalid sound {sound} specified"
},
"unknown_exception": {
"message": "Unknown error occurred: {error}"
}
},
"selector": {
Expand Down
11 changes: 5 additions & 6 deletions homeassistant/components/blebox/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from blebox_uniapi.error import Error
from blebox_uniapi.session import ApiHost

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
CONF_HOST,
CONF_PASSWORD,
Expand All @@ -18,10 +17,9 @@
from homeassistant.exceptions import ConfigEntryNotReady

from .const import DEFAULT_SETUP_TIMEOUT
from .coordinator import BleBoxConfigEntry, BleBoxCoordinator
from .helpers import get_maybe_authenticated_session

type BleBoxConfigEntry = ConfigEntry[Box]

_LOGGER = logging.getLogger(__name__)

PLATFORMS = [
Expand All @@ -35,8 +33,6 @@
Platform.UPDATE,
]

PARALLEL_UPDATES = 0


async def async_setup_entry(hass: HomeAssistant, entry: BleBoxConfigEntry) -> bool:
"""Set up BleBox devices from a config entry."""
Expand All @@ -58,7 +54,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: BleBoxConfigEntry) -> bo
_LOGGER.error("Identify failed at %s:%d (%s)", api_host.host, api_host.port, ex)
raise ConfigEntryNotReady from ex

entry.runtime_data = product
coordinator = BleBoxCoordinator(hass, entry, product)
await coordinator.async_config_entry_first_refresh()

entry.runtime_data = coordinator

await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

Expand Down
17 changes: 12 additions & 5 deletions homeassistant/components/blebox/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback

from . import BleBoxConfigEntry
from .coordinator import BleBoxCoordinator
from .entity import BleBoxEntity

PARALLEL_UPDATES = 0

BINARY_SENSOR_TYPES = (
BinarySensorEntityDescription(
key="moisture",
Expand All @@ -27,23 +30,27 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up a BleBox entry."""
coordinator = config_entry.runtime_data
entities = [
BleBoxBinarySensorEntity(feature, description)
for feature in config_entry.runtime_data.features.get("binary_sensors", [])
BleBoxBinarySensorEntity(coordinator, feature, description)
for feature in coordinator.box.features.get("binary_sensors", [])
for description in BINARY_SENSOR_TYPES
if description.key == feature.device_class
]
async_add_entities(entities, True)
async_add_entities(entities)


class BleBoxBinarySensorEntity(BleBoxEntity[BinarySensorFeature], BinarySensorEntity):
"""Representation of a BleBox binary sensor feature."""

def __init__(
self, feature: BinarySensorFeature, description: BinarySensorEntityDescription
self,
coordinator: BleBoxCoordinator,
feature: BinarySensorFeature,
description: BinarySensorEntityDescription,
) -> None:
"""Initialize a BleBox binary sensor feature."""
super().__init__(feature)
super().__init__(coordinator, feature)
self.entity_description = description

@property
Expand Down
18 changes: 13 additions & 5 deletions homeassistant/components/blebox/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback

from . import BleBoxConfigEntry
from .coordinator import BleBoxCoordinator
from .entity import BleBoxEntity
from .util import blebox_command

PARALLEL_UPDATES = 1


async def async_setup_entry(
Expand All @@ -16,19 +20,22 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up a BleBox button entry."""
coordinator = config_entry.runtime_data
entities = [
BleBoxButtonEntity(feature)
for feature in config_entry.runtime_data.features.get("buttons", [])
BleBoxButtonEntity(coordinator, feature)
for feature in coordinator.box.features.get("buttons", [])
]
async_add_entities(entities, True)
async_add_entities(entities)


class BleBoxButtonEntity(BleBoxEntity[blebox_uniapi.button.Button], ButtonEntity):
"""Representation of BleBox buttons."""

def __init__(self, feature: blebox_uniapi.button.Button) -> None:
def __init__(
self, coordinator: BleBoxCoordinator, feature: blebox_uniapi.button.Button
) -> None:
"""Initialize a BleBox button feature."""
super().__init__(feature)
super().__init__(coordinator, feature)
self._attr_icon = self.get_icon()

def get_icon(self) -> str | None:
Expand All @@ -45,6 +52,7 @@ def get_icon(self) -> str | None:
return "mdi:arrow-down-circle"
return None

@blebox_command
async def async_press(self) -> None:
"""Handle the button press."""
await self._feature.set()
13 changes: 8 additions & 5 deletions homeassistant/components/blebox/climate.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""BleBox climate entity."""

from datetime import timedelta
from typing import Any

import blebox_uniapi.climate
Expand All @@ -17,8 +16,9 @@

from . import BleBoxConfigEntry
from .entity import BleBoxEntity
from .util import blebox_command

SCAN_INTERVAL = timedelta(seconds=5)
PARALLEL_UPDATES = 1

BLEBOX_TO_HVACMODE = {
0: HVACMode.OFF,
Expand All @@ -40,11 +40,12 @@ async def async_setup_entry(
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up a BleBox climate entity."""
coordinator = config_entry.runtime_data
entities = [
BleBoxClimateEntity(feature)
for feature in config_entry.runtime_data.features.get("climates", [])
BleBoxClimateEntity(coordinator, feature)
for feature in coordinator.box.features.get("climates", [])
]
async_add_entities(entities, True)
async_add_entities(entities)


class BleBoxClimateEntity(BleBoxEntity[blebox_uniapi.climate.Climate], ClimateEntity):
Expand Down Expand Up @@ -108,6 +109,7 @@ def target_temperature(self) -> float | None:
"""Return the desired thermostat temperature."""
return self._feature.desired

@blebox_command
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set the climate entity mode."""
if hvac_mode in [HVACMode.HEAT, HVACMode.COOL]:
Expand All @@ -116,6 +118,7 @@ async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:

await self._feature.async_off()

@blebox_command
async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set the thermostat temperature."""
value = kwargs[ATTR_TEMPERATURE]
Expand Down
Loading
Loading