Skip to content

Commit 40d7f2a

Browse files
authored
2 parents 013346c + 13b717e commit 40d7f2a

File tree

128 files changed

+1796
-618
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

128 files changed

+1796
-618
lines changed

CODEOWNERS

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

homeassistant/components/accuweather/const.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,4 @@
7171
}
7272
UPDATE_INTERVAL_OBSERVATION = timedelta(minutes=10)
7373
UPDATE_INTERVAL_DAILY_FORECAST = timedelta(hours=6)
74-
UPDATE_INTERVAL_HOURLY_FORECAST = timedelta(hours=30)
74+
UPDATE_INTERVAL_HOURLY_FORECAST = timedelta(minutes=30)

homeassistant/components/accuweather/icons.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
{
22
"entity": {
33
"sensor": {
4+
"air_quality": {
5+
"default": "mdi:air-filter"
6+
},
47
"cloud_ceiling": {
58
"default": "mdi:weather-fog"
69
},
@@ -34,9 +37,6 @@
3437
"thunderstorm_probability_night": {
3538
"default": "mdi:weather-lightning"
3639
},
37-
"translation_key": {
38-
"default": "mdi:air-filter"
39-
},
4040
"tree_pollen": {
4141
"default": "mdi:tree-outline"
4242
},

homeassistant/components/airgradient/update.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
"""Airgradient Update platform."""
22

33
from datetime import timedelta
4+
import logging
45

6+
from airgradient import AirGradientConnectionError
57
from propcache.api import cached_property
68

79
from homeassistant.components.update import UpdateDeviceClass, UpdateEntity
@@ -13,6 +15,7 @@
1315

1416
PARALLEL_UPDATES = 1
1517
SCAN_INTERVAL = timedelta(hours=1)
18+
_LOGGER = logging.getLogger(__name__)
1619

1720

1821
async def async_setup_entry(
@@ -31,6 +34,7 @@ class AirGradientUpdate(AirGradientEntity, UpdateEntity):
3134
"""Representation of Airgradient Update."""
3235

3336
_attr_device_class = UpdateDeviceClass.FIRMWARE
37+
_server_unreachable_logged = False
3438

3539
def __init__(self, coordinator: AirGradientCoordinator) -> None:
3640
"""Initialize the entity."""
@@ -47,10 +51,27 @@ def installed_version(self) -> str:
4751
"""Return the installed version of the entity."""
4852
return self.coordinator.data.measures.firmware_version
4953

54+
@property
55+
def available(self) -> bool:
56+
"""Return if entity is available."""
57+
return super().available and self._attr_available
58+
5059
async def async_update(self) -> None:
5160
"""Update the entity."""
52-
self._attr_latest_version = (
53-
await self.coordinator.client.get_latest_firmware_version(
54-
self.coordinator.serial_number
61+
try:
62+
self._attr_latest_version = (
63+
await self.coordinator.client.get_latest_firmware_version(
64+
self.coordinator.serial_number
65+
)
5566
)
56-
)
67+
except AirGradientConnectionError:
68+
self._attr_latest_version = None
69+
self._attr_available = False
70+
if not self._server_unreachable_logged:
71+
_LOGGER.error(
72+
"Unable to connect to AirGradient server to check for updates"
73+
)
74+
self._server_unreachable_logged = True
75+
else:
76+
self._server_unreachable_logged = False
77+
self._attr_available = True

homeassistant/components/airos/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
"documentation": "https://www.home-assistant.io/integrations/airos",
77
"iot_class": "local_polling",
88
"quality_scale": "bronze",
9-
"requirements": ["airos==0.5.4"]
9+
"requirements": ["airos==0.5.5"]
1010
}

homeassistant/components/alexa_devices/binary_sensor.py

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
from homeassistant.const import EntityCategory
1919
from homeassistant.core import HomeAssistant
2020
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
21+
import homeassistant.helpers.entity_registry as er
2122

23+
from .const import _LOGGER, DOMAIN
2224
from .coordinator import AmazonConfigEntry
2325
from .entity import AmazonEntity
2426
from .utils import async_update_unique_id
@@ -51,11 +53,47 @@ class AmazonBinarySensorEntityDescription(BinarySensorEntityDescription):
5153
),
5254
is_supported=lambda device, key: device.sensors.get(key) is not None,
5355
is_available_fn=lambda device, key: (
54-
device.online and device.sensors[key].error is False
56+
device.online
57+
and (sensor := device.sensors.get(key)) is not None
58+
and sensor.error is False
5559
),
5660
),
5761
)
5862

63+
DEPRECATED_BINARY_SENSORS: Final = (
64+
AmazonBinarySensorEntityDescription(
65+
key="bluetooth",
66+
entity_category=EntityCategory.DIAGNOSTIC,
67+
translation_key="bluetooth",
68+
is_on_fn=lambda device, key: False,
69+
),
70+
AmazonBinarySensorEntityDescription(
71+
key="babyCryDetectionState",
72+
translation_key="baby_cry_detection",
73+
is_on_fn=lambda device, key: False,
74+
),
75+
AmazonBinarySensorEntityDescription(
76+
key="beepingApplianceDetectionState",
77+
translation_key="beeping_appliance_detection",
78+
is_on_fn=lambda device, key: False,
79+
),
80+
AmazonBinarySensorEntityDescription(
81+
key="coughDetectionState",
82+
translation_key="cough_detection",
83+
is_on_fn=lambda device, key: False,
84+
),
85+
AmazonBinarySensorEntityDescription(
86+
key="dogBarkDetectionState",
87+
translation_key="dog_bark_detection",
88+
is_on_fn=lambda device, key: False,
89+
),
90+
AmazonBinarySensorEntityDescription(
91+
key="waterSoundsDetectionState",
92+
translation_key="water_sounds_detection",
93+
is_on_fn=lambda device, key: False,
94+
),
95+
)
96+
5997

6098
async def async_setup_entry(
6199
hass: HomeAssistant,
@@ -66,6 +104,8 @@ async def async_setup_entry(
66104

67105
coordinator = entry.runtime_data
68106

107+
entity_registry = er.async_get(hass)
108+
69109
# Replace unique id for "detectionState" binary sensor
70110
await async_update_unique_id(
71111
hass,
@@ -75,6 +115,16 @@ async def async_setup_entry(
75115
"detectionState",
76116
)
77117

118+
# Clean up deprecated sensors
119+
for sensor_desc in DEPRECATED_BINARY_SENSORS:
120+
for serial_num in coordinator.data:
121+
unique_id = f"{serial_num}-{sensor_desc.key}"
122+
if entity_id := entity_registry.async_get_entity_id(
123+
BINARY_SENSOR_DOMAIN, DOMAIN, unique_id
124+
):
125+
_LOGGER.debug("Removing deprecated entity %s", entity_id)
126+
entity_registry.async_remove(entity_id)
127+
78128
known_devices: set[str] = set()
79129

80130
def _check_device() -> None:

homeassistant/components/alexa_devices/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@
88
"iot_class": "cloud_polling",
99
"loggers": ["aioamazondevices"],
1010
"quality_scale": "platinum",
11-
"requirements": ["aioamazondevices==6.2.7"]
11+
"requirements": ["aioamazondevices==6.4.0"]
1212
}

homeassistant/components/alexa_devices/sensor.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,19 @@ class AmazonSensorEntityDescription(SensorEntityDescription):
3232

3333
native_unit_of_measurement_fn: Callable[[AmazonDevice, str], str] | None = None
3434
is_available_fn: Callable[[AmazonDevice, str], bool] = lambda device, key: (
35-
device.online and device.sensors[key].error is False
35+
device.online
36+
and (sensor := device.sensors.get(key)) is not None
37+
and sensor.error is False
3638
)
3739

3840

3941
SENSORS: Final = (
4042
AmazonSensorEntityDescription(
4143
key="temperature",
4244
device_class=SensorDeviceClass.TEMPERATURE,
43-
native_unit_of_measurement_fn=lambda device, _key: (
45+
native_unit_of_measurement_fn=lambda device, key: (
4446
UnitOfTemperature.CELSIUS
45-
if device.sensors[_key].scale == "CELSIUS"
47+
if key in device.sensors and device.sensors[key].scale == "CELSIUS"
4648
else UnitOfTemperature.FAHRENHEIT
4749
),
4850
state_class=SensorStateClass.MEASUREMENT,

homeassistant/components/alexa_devices/switch.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@
1818

1919
from .coordinator import AmazonConfigEntry
2020
from .entity import AmazonEntity
21-
from .utils import alexa_api_call, async_update_unique_id
21+
from .utils import (
22+
alexa_api_call,
23+
async_remove_dnd_from_virtual_group,
24+
async_update_unique_id,
25+
)
2226

2327
PARALLEL_UPDATES = 1
2428

@@ -29,7 +33,9 @@ class AmazonSwitchEntityDescription(SwitchEntityDescription):
2933

3034
is_on_fn: Callable[[AmazonDevice], bool]
3135
is_available_fn: Callable[[AmazonDevice, str], bool] = lambda device, key: (
32-
device.online and device.sensors[key].error is False
36+
device.online
37+
and (sensor := device.sensors.get(key)) is not None
38+
and sensor.error is False
3339
)
3440
method: str
3541

@@ -58,6 +64,9 @@ async def async_setup_entry(
5864
hass, coordinator, SWITCH_DOMAIN, "do_not_disturb", "dnd"
5965
)
6066

67+
# Remove DND switch from virtual groups
68+
await async_remove_dnd_from_virtual_group(hass, coordinator)
69+
6170
known_devices: set[str] = set()
6271

6372
def _check_device() -> None:

homeassistant/components/alexa_devices/utils.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
from functools import wraps
55
from typing import Any, Concatenate
66

7+
from aioamazondevices.const import SPEAKER_GROUP_FAMILY
78
from aioamazondevices.exceptions import CannotConnect, CannotRetrieveData
89

10+
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
911
from homeassistant.core import HomeAssistant
1012
from homeassistant.exceptions import HomeAssistantError
1113
import homeassistant.helpers.entity_registry as er
@@ -61,3 +63,21 @@ async def async_update_unique_id(
6163

6264
# Update the registry with the new unique_id
6365
entity_registry.async_update_entity(entity_id, new_unique_id=new_unique_id)
66+
67+
68+
async def async_remove_dnd_from_virtual_group(
69+
hass: HomeAssistant,
70+
coordinator: AmazonDevicesCoordinator,
71+
) -> None:
72+
"""Remove entity DND from virtual group."""
73+
entity_registry = er.async_get(hass)
74+
75+
for serial_num in coordinator.data:
76+
unique_id = f"{serial_num}-do_not_disturb"
77+
entity_id = entity_registry.async_get_entity_id(
78+
DOMAIN, SWITCH_DOMAIN, unique_id
79+
)
80+
is_group = coordinator.data[serial_num].device_family == SPEAKER_GROUP_FAMILY
81+
if entity_id and is_group:
82+
entity_registry.async_remove(entity_id)
83+
_LOGGER.debug("Removed DND switch from virtual group %s", entity_id)

0 commit comments

Comments
 (0)