From 8c6547f1b64f4a3d9f10090b97383353c9367892 Mon Sep 17 00:00:00 2001 From: vexofp Date: Tue, 2 Jan 2024 05:59:40 -0500 Subject: [PATCH 01/21] Pass default SSLContext instances to Octoprint custom HTTP sessions (#105351) --- homeassistant/components/octoprint/__init__.py | 5 ++++- homeassistant/components/octoprint/config_flow.py | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/octoprint/__init__.py b/homeassistant/components/octoprint/__init__.py index 5fd2182ca00..50ba6c964f3 100644 --- a/homeassistant/components/octoprint/__init__.py +++ b/homeassistant/components/octoprint/__init__.py @@ -26,6 +26,7 @@ from homeassistant.core import Event, HomeAssistant, callback import homeassistant.helpers.config_validation as cv from homeassistant.helpers.typing import ConfigType from homeassistant.util import slugify as util_slugify +from homeassistant.util.ssl import get_default_context, get_default_no_verify_context from .const import DOMAIN from .coordinator import OctoprintDataUpdateCoordinator @@ -159,7 +160,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: connector = aiohttp.TCPConnector( force_close=True, - ssl=False if not entry.data[CONF_VERIFY_SSL] else None, + ssl=get_default_no_verify_context() + if not entry.data[CONF_VERIFY_SSL] + else get_default_context(), ) session = aiohttp.ClientSession(connector=connector) diff --git a/homeassistant/components/octoprint/config_flow.py b/homeassistant/components/octoprint/config_flow.py index 09ac53ecf5b..696898400bf 100644 --- a/homeassistant/components/octoprint/config_flow.py +++ b/homeassistant/components/octoprint/config_flow.py @@ -24,6 +24,7 @@ from homeassistant.const import ( ) from homeassistant.data_entry_flow import FlowResult import homeassistant.helpers.config_validation as cv +from homeassistant.util.ssl import get_default_context, get_default_no_verify_context from .const import DOMAIN @@ -264,7 +265,9 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): connector = aiohttp.TCPConnector( force_close=True, - ssl=False if not verify_ssl else None, + ssl=get_default_no_verify_context() + if not verify_ssl + else get_default_context(), ) session = aiohttp.ClientSession(connector=connector) self._sessions.append(session) From 18f663d4980cf2d07e81a247034fb9bbc0e2d0b4 Mon Sep 17 00:00:00 2001 From: Allen Porter Date: Tue, 23 Jan 2024 01:50:00 -0800 Subject: [PATCH 02/21] Reduce overhead for google calendar state updates (#108133) --- homeassistant/components/google/calendar.py | 30 +++++++++++++++++-- homeassistant/components/google/manifest.json | 2 +- requirements_all.txt | 1 + requirements_test_all.txt | 1 + 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/google/calendar.py b/homeassistant/components/google/calendar.py index 3e34a7234a4..88f59ff44f7 100644 --- a/homeassistant/components/google/calendar.py +++ b/homeassistant/components/google/calendar.py @@ -4,6 +4,7 @@ from __future__ import annotations from collections.abc import Iterable from datetime import datetime, timedelta +import itertools import logging from typing import Any, cast @@ -18,6 +19,7 @@ from gcal_sync.model import AccessRole, DateOrDatetime, Event from gcal_sync.store import ScopedCalendarStore from gcal_sync.sync import CalendarEventSyncManager from gcal_sync.timeline import Timeline +from ical.iter import SortableItemValue from homeassistant.components.calendar import ( CREATE_EVENT_SCHEMA, @@ -76,6 +78,9 @@ from .const import ( _LOGGER = logging.getLogger(__name__) MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=15) +# Maximum number of upcoming events to consider for state changes between +# coordinator updates. +MAX_UPCOMING_EVENTS = 20 # Avoid syncing super old data on initial syncs. Note that old but active # recurring events are still included. @@ -244,6 +249,22 @@ async def async_setup_entry( ) +def _truncate_timeline(timeline: Timeline, max_events: int) -> Timeline: + """Truncate the timeline to a maximum number of events. + + This is used to avoid repeated expansion of recurring events during + state machine updates. + """ + upcoming = timeline.active_after(dt_util.now()) + truncated = list(itertools.islice(upcoming, max_events)) + return Timeline( + [ + SortableItemValue(event.timespan_of(dt_util.DEFAULT_TIME_ZONE), event) + for event in truncated + ] + ) + + class CalendarSyncUpdateCoordinator(DataUpdateCoordinator[Timeline]): """Coordinator for calendar RPC calls that use an efficient sync.""" @@ -263,6 +284,7 @@ class CalendarSyncUpdateCoordinator(DataUpdateCoordinator[Timeline]): update_interval=MIN_TIME_BETWEEN_UPDATES, ) self.sync = sync + self._upcoming_timeline: Timeline | None = None async def _async_update_data(self) -> Timeline: """Fetch data from API endpoint.""" @@ -271,9 +293,11 @@ class CalendarSyncUpdateCoordinator(DataUpdateCoordinator[Timeline]): except ApiException as err: raise UpdateFailed(f"Error communicating with API: {err}") from err - return await self.sync.store_service.async_get_timeline( + timeline = await self.sync.store_service.async_get_timeline( dt_util.DEFAULT_TIME_ZONE ) + self._upcoming_timeline = _truncate_timeline(timeline, MAX_UPCOMING_EVENTS) + return timeline async def async_get_events( self, start_date: datetime, end_date: datetime @@ -291,8 +315,8 @@ class CalendarSyncUpdateCoordinator(DataUpdateCoordinator[Timeline]): @property def upcoming(self) -> Iterable[Event] | None: """Return upcoming events if any.""" - if self.data: - return self.data.active_after(dt_util.now()) + if self._upcoming_timeline: + return self._upcoming_timeline.active_after(dt_util.now()) return None diff --git a/homeassistant/components/google/manifest.json b/homeassistant/components/google/manifest.json index 27e462a380e..d0705f9382a 100644 --- a/homeassistant/components/google/manifest.json +++ b/homeassistant/components/google/manifest.json @@ -7,5 +7,5 @@ "documentation": "https://www.home-assistant.io/integrations/calendar.google", "iot_class": "cloud_polling", "loggers": ["googleapiclient"], - "requirements": ["gcal-sync==6.0.3", "oauth2client==4.1.3"] + "requirements": ["gcal-sync==6.0.3", "oauth2client==4.1.3", "ical==6.1.1"] } diff --git a/requirements_all.txt b/requirements_all.txt index cff90b6a6cd..bbe4a6fd90c 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1076,6 +1076,7 @@ ibeacon-ble==1.0.1 # homeassistant.components.watson_iot ibmiotf==0.3.4 +# homeassistant.components.google # homeassistant.components.local_calendar # homeassistant.components.local_todo ical==6.1.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 8877471660a..a2bbeea023a 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -860,6 +860,7 @@ iaqualink==0.5.0 # homeassistant.components.ibeacon ibeacon-ble==1.0.1 +# homeassistant.components.google # homeassistant.components.local_calendar # homeassistant.components.local_todo ical==6.1.1 From 3a510f84a737a5d12a95f4b5b53b459eb75b7c13 Mon Sep 17 00:00:00 2001 From: jmwaldrip Date: Mon, 22 Jan 2024 12:22:54 -0800 Subject: [PATCH 03/21] Fix SleepIQ setting FootWarmer timer (#108433) * Fixing foot warmer timer bug * Fixing bug where temperature wasnt assigned to number entity causing tests to fail --- homeassistant/components/sleepiq/number.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/sleepiq/number.py b/homeassistant/components/sleepiq/number.py index 520e11bb331..4f90ef7dbdc 100644 --- a/homeassistant/components/sleepiq/number.py +++ b/homeassistant/components/sleepiq/number.py @@ -5,7 +5,13 @@ from collections.abc import Callable, Coroutine from dataclasses import dataclass from typing import Any, cast -from asyncsleepiq import SleepIQActuator, SleepIQBed, SleepIQFootWarmer, SleepIQSleeper +from asyncsleepiq import ( + FootWarmingTemps, + SleepIQActuator, + SleepIQBed, + SleepIQFootWarmer, + SleepIQSleeper, +) from homeassistant.components.number import NumberEntity, NumberEntityDescription from homeassistant.config_entries import ConfigEntry @@ -79,6 +85,10 @@ def _get_sleeper_unique_id(bed: SleepIQBed, sleeper: SleepIQSleeper) -> str: async def _async_set_foot_warmer_time( foot_warmer: SleepIQFootWarmer, time: int ) -> None: + temperature = FootWarmingTemps(foot_warmer.temperature) + if temperature != FootWarmingTemps.OFF: + await foot_warmer.turn_on(temperature, time) + foot_warmer.timer = time From 279f7264e74c67b584b429dc363ea831718e6062 Mon Sep 17 00:00:00 2001 From: Florian Kisser Date: Sun, 21 Jan 2024 02:37:13 +0100 Subject: [PATCH 04/21] Fix zha illuminance measured value mapping (#108547) --- homeassistant/components/zha/sensor.py | 6 +++++- tests/components/zha/test_sensor.py | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/zha/sensor.py b/homeassistant/components/zha/sensor.py index ea5d09dd6f4..8bf8ca96d77 100644 --- a/homeassistant/components/zha/sensor.py +++ b/homeassistant/components/zha/sensor.py @@ -481,8 +481,12 @@ class Illuminance(Sensor): _attr_state_class: SensorStateClass = SensorStateClass.MEASUREMENT _attr_native_unit_of_measurement = LIGHT_LUX - def formatter(self, value: int) -> int: + def formatter(self, value: int) -> int | None: """Convert illumination data.""" + if value == 0: + return 0 + if value == 0xFFFF: + return None return round(pow(10, ((value - 1) / 10000))) diff --git a/tests/components/zha/test_sensor.py b/tests/components/zha/test_sensor.py index d9a61b12357..0d3035f9717 100644 --- a/tests/components/zha/test_sensor.py +++ b/tests/components/zha/test_sensor.py @@ -136,6 +136,12 @@ async def async_test_illuminance(hass, cluster, entity_id): await send_attributes_report(hass, cluster, {1: 1, 0: 10, 2: 20}) assert_state(hass, entity_id, "1", LIGHT_LUX) + await send_attributes_report(hass, cluster, {1: 0, 0: 0, 2: 20}) + assert_state(hass, entity_id, "0", LIGHT_LUX) + + await send_attributes_report(hass, cluster, {1: 0, 0: 0xFFFF, 2: 20}) + assert_state(hass, entity_id, "unknown", LIGHT_LUX) + async def async_test_metering(hass, cluster, entity_id): """Test Smart Energy metering sensor.""" From 4db6f7ce59e8372572d1b495ccc6b2f492f61fdd Mon Sep 17 00:00:00 2001 From: Matrix Date: Sun, 28 Jan 2024 13:38:42 +0800 Subject: [PATCH 05/21] Bump yolink-api to 0.3.6 fix aiomqtt breaking changes (#108555) * bump yolink-api to 0.3.5 * bump yolink-api to 0.3.6 --- homeassistant/components/yolink/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/yolink/manifest.json b/homeassistant/components/yolink/manifest.json index a42687a3551..6fd62ce571c 100644 --- a/homeassistant/components/yolink/manifest.json +++ b/homeassistant/components/yolink/manifest.json @@ -6,5 +6,5 @@ "dependencies": ["auth", "application_credentials"], "documentation": "https://www.home-assistant.io/integrations/yolink", "iot_class": "cloud_push", - "requirements": ["yolink-api==0.3.4"] + "requirements": ["yolink-api==0.3.6"] } diff --git a/requirements_all.txt b/requirements_all.txt index bbe4a6fd90c..beed6c6eb01 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2843,7 +2843,7 @@ yeelight==0.7.14 yeelightsunflower==0.0.10 # homeassistant.components.yolink -yolink-api==0.3.4 +yolink-api==0.3.6 # homeassistant.components.youless youless-api==1.0.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index a2bbeea023a..1ef4e6809a9 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -2151,7 +2151,7 @@ yalexs==1.10.0 yeelight==0.7.14 # homeassistant.components.yolink -yolink-api==0.3.4 +yolink-api==0.3.6 # homeassistant.components.youless youless-api==1.0.1 From bbe80c60491aca4971e4355235380ac62d3d5b1a Mon Sep 17 00:00:00 2001 From: Michal Ziemski Date: Tue, 23 Jan 2024 15:14:41 +0100 Subject: [PATCH 06/21] Update openerz-api to 0.3.0 (#108575) --- homeassistant/components/openerz/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/openerz/manifest.json b/homeassistant/components/openerz/manifest.json index 181e0bd870a..c7a5a202568 100644 --- a/homeassistant/components/openerz/manifest.json +++ b/homeassistant/components/openerz/manifest.json @@ -5,5 +5,5 @@ "documentation": "https://www.home-assistant.io/integrations/openerz", "iot_class": "cloud_polling", "loggers": ["openerz_api"], - "requirements": ["openerz-api==0.2.0"] + "requirements": ["openerz-api==0.3.0"] } diff --git a/requirements_all.txt b/requirements_all.txt index beed6c6eb01..062423be67e 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1414,7 +1414,7 @@ openai==1.3.8 # opencv-python-headless==4.6.0.66 # homeassistant.components.openerz -openerz-api==0.2.0 +openerz-api==0.3.0 # homeassistant.components.openevse openevsewifi==1.1.2 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 1ef4e6809a9..acc7b389699 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1111,7 +1111,7 @@ open-meteo==0.3.1 openai==1.3.8 # homeassistant.components.openerz -openerz-api==0.2.0 +openerz-api==0.3.0 # homeassistant.components.openhome openhomedevice==2.2.0 From b17b4c3350518661f9278ecfffb148b825fe8edf Mon Sep 17 00:00:00 2001 From: Simone Chemelli Date: Mon, 22 Jan 2024 13:51:17 +0100 Subject: [PATCH 07/21] Bump aiovodafone to 0.5.4 (#108592) --- homeassistant/components/vodafone_station/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/vodafone_station/manifest.json b/homeassistant/components/vodafone_station/manifest.json index 20ea4db057e..ced871b7616 100644 --- a/homeassistant/components/vodafone_station/manifest.json +++ b/homeassistant/components/vodafone_station/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/vodafone_station", "iot_class": "local_polling", "loggers": ["aiovodafone"], - "requirements": ["aiovodafone==0.4.3"] + "requirements": ["aiovodafone==0.5.4"] } diff --git a/requirements_all.txt b/requirements_all.txt index 062423be67e..3d253b3a953 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -383,7 +383,7 @@ aiounifi==69 aiovlc==0.1.0 # homeassistant.components.vodafone_station -aiovodafone==0.4.3 +aiovodafone==0.5.4 # homeassistant.components.waqi aiowaqi==3.0.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index acc7b389699..7871af2ffb2 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -356,7 +356,7 @@ aiounifi==69 aiovlc==0.1.0 # homeassistant.components.vodafone_station -aiovodafone==0.4.3 +aiovodafone==0.5.4 # homeassistant.components.waqi aiowaqi==3.0.1 From 1b8c91dcb711a77a0340cabb8631af11f8be9f2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A5le=20Stor=C3=B8=20Hauknes?= Date: Sun, 21 Jan 2024 22:20:07 +0100 Subject: [PATCH 08/21] Bump airthings-ble to 0.6.0 (#108612) --- homeassistant/components/airthings_ble/__init__.py | 3 ++- homeassistant/components/airthings_ble/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/airthings_ble/__init__.py b/homeassistant/components/airthings_ble/__init__.py index 1d62442f14d..3a97813741b 100644 --- a/homeassistant/components/airthings_ble/__init__.py +++ b/homeassistant/components/airthings_ble/__init__.py @@ -40,10 +40,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: f"Could not find Airthings device with address {address}" ) + airthings = AirthingsBluetoothDeviceData(_LOGGER, elevation, is_metric) + async def _async_update_method() -> AirthingsDevice: """Get data from Airthings BLE.""" ble_device = bluetooth.async_ble_device_from_address(hass, address) - airthings = AirthingsBluetoothDeviceData(_LOGGER, elevation, is_metric) try: data = await airthings.update_device(ble_device) # type: ignore[arg-type] diff --git a/homeassistant/components/airthings_ble/manifest.json b/homeassistant/components/airthings_ble/manifest.json index cb7114ff8ff..03b42410d66 100644 --- a/homeassistant/components/airthings_ble/manifest.json +++ b/homeassistant/components/airthings_ble/manifest.json @@ -24,5 +24,5 @@ "dependencies": ["bluetooth_adapters"], "documentation": "https://www.home-assistant.io/integrations/airthings_ble", "iot_class": "local_polling", - "requirements": ["airthings-ble==0.5.6-2"] + "requirements": ["airthings-ble==0.6.0"] } diff --git a/requirements_all.txt b/requirements_all.txt index 3d253b3a953..99bde907caa 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -404,7 +404,7 @@ aioymaps==1.2.2 airly==1.1.0 # homeassistant.components.airthings_ble -airthings-ble==0.5.6-2 +airthings-ble==0.6.0 # homeassistant.components.airthings airthings-cloud==0.1.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 7871af2ffb2..3262ea26b88 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -377,7 +377,7 @@ aioymaps==1.2.2 airly==1.1.0 # homeassistant.components.airthings_ble -airthings-ble==0.5.6-2 +airthings-ble==0.6.0 # homeassistant.components.airthings airthings-cloud==0.1.0 From 58c96ff79643e4fdd7d74234d60ef886c06de2fb Mon Sep 17 00:00:00 2001 From: Jan Bouwhuis Date: Tue, 23 Jan 2024 23:36:44 +0100 Subject: [PATCH 09/21] Fix alexa fails reporting the state in specific cases (#108743) * Fix alexa fails reporting the state in specific cases * More cases --- .../components/alexa/capabilities.py | 32 +++++++++++-------- homeassistant/components/alexa/entities.py | 5 +-- homeassistant/components/alexa/handlers.py | 8 ++--- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/homeassistant/components/alexa/capabilities.py b/homeassistant/components/alexa/capabilities.py index ab3bd8591fd..d30f3f7376d 100644 --- a/homeassistant/components/alexa/capabilities.py +++ b/homeassistant/components/alexa/capabilities.py @@ -860,8 +860,8 @@ class AlexaInputController(AlexaCapability): def inputs(self) -> list[dict[str, str]] | None: """Return the list of valid supported inputs.""" - source_list: list[Any] = self.entity.attributes.get( - media_player.ATTR_INPUT_SOURCE_LIST, [] + source_list: list[Any] = ( + self.entity.attributes.get(media_player.ATTR_INPUT_SOURCE_LIST) or [] ) return AlexaInputController.get_valid_inputs(source_list) @@ -1196,7 +1196,7 @@ class AlexaThermostatController(AlexaCapability): return None supported_modes: list[str] = [] - hvac_modes = self.entity.attributes.get(climate.ATTR_HVAC_MODES, []) + hvac_modes = self.entity.attributes.get(climate.ATTR_HVAC_MODES) or [] for mode in hvac_modes: if thermostat_mode := API_THERMOSTAT_MODES.get(mode): supported_modes.append(thermostat_mode) @@ -1422,18 +1422,22 @@ class AlexaModeController(AlexaCapability): # Humidifier mode if self.instance == f"{humidifier.DOMAIN}.{humidifier.ATTR_MODE}": - mode = self.entity.attributes.get(humidifier.ATTR_MODE, None) - if mode in self.entity.attributes.get(humidifier.ATTR_AVAILABLE_MODES, []): + mode = self.entity.attributes.get(humidifier.ATTR_MODE) + modes: list[str] = ( + self.entity.attributes.get(humidifier.ATTR_AVAILABLE_MODES) or [] + ) + if mode in modes: return f"{humidifier.ATTR_MODE}.{mode}" # Water heater operation mode if self.instance == f"{water_heater.DOMAIN}.{water_heater.ATTR_OPERATION_MODE}": operation_mode = self.entity.attributes.get( - water_heater.ATTR_OPERATION_MODE, None + water_heater.ATTR_OPERATION_MODE ) - if operation_mode in self.entity.attributes.get( - water_heater.ATTR_OPERATION_LIST, [] - ): + operation_modes: list[str] = ( + self.entity.attributes.get(water_heater.ATTR_OPERATION_LIST) or [] + ) + if operation_mode in operation_modes: return f"{water_heater.ATTR_OPERATION_MODE}.{operation_mode}" # Cover Position @@ -1492,7 +1496,7 @@ class AlexaModeController(AlexaCapability): self._resource = AlexaModeResource( [AlexaGlobalCatalog.SETTING_PRESET], False ) - preset_modes = self.entity.attributes.get(fan.ATTR_PRESET_MODES, []) + preset_modes = self.entity.attributes.get(fan.ATTR_PRESET_MODES) or [] for preset_mode in preset_modes: self._resource.add_mode( f"{fan.ATTR_PRESET_MODE}.{preset_mode}", [preset_mode] @@ -1508,7 +1512,7 @@ class AlexaModeController(AlexaCapability): # Humidifier modes if self.instance == f"{humidifier.DOMAIN}.{humidifier.ATTR_MODE}": self._resource = AlexaModeResource([AlexaGlobalCatalog.SETTING_MODE], False) - modes = self.entity.attributes.get(humidifier.ATTR_AVAILABLE_MODES, []) + modes = self.entity.attributes.get(humidifier.ATTR_AVAILABLE_MODES) or [] for mode in modes: self._resource.add_mode(f"{humidifier.ATTR_MODE}.{mode}", [mode]) # Humidifiers or Fans with a single mode completely break Alexa discovery, @@ -1522,8 +1526,8 @@ class AlexaModeController(AlexaCapability): # Water heater operation modes if self.instance == f"{water_heater.DOMAIN}.{water_heater.ATTR_OPERATION_MODE}": self._resource = AlexaModeResource([AlexaGlobalCatalog.SETTING_MODE], False) - operation_modes = self.entity.attributes.get( - water_heater.ATTR_OPERATION_LIST, [] + operation_modes = ( + self.entity.attributes.get(water_heater.ATTR_OPERATION_LIST) or [] ) for operation_mode in operation_modes: self._resource.add_mode( @@ -2368,7 +2372,7 @@ class AlexaEqualizerController(AlexaCapability): """Return the sound modes supported in the configurations object.""" configurations = None supported_sound_modes = self.get_valid_inputs( - self.entity.attributes.get(media_player.ATTR_SOUND_MODE_LIST, []) + self.entity.attributes.get(media_player.ATTR_SOUND_MODE_LIST) or [] ) if supported_sound_modes: configurations = {"modes": {"supported": supported_sound_modes}} diff --git a/homeassistant/components/alexa/entities.py b/homeassistant/components/alexa/entities.py index d0e265b8454..70679f8dafb 100644 --- a/homeassistant/components/alexa/entities.py +++ b/homeassistant/components/alexa/entities.py @@ -478,7 +478,7 @@ class ClimateCapabilities(AlexaEntity): if ( self.entity.domain == climate.DOMAIN and climate.HVACMode.OFF - in self.entity.attributes.get(climate.ATTR_HVAC_MODES, []) + in (self.entity.attributes.get(climate.ATTR_HVAC_MODES) or []) or self.entity.domain == water_heater.DOMAIN and (supported_features & water_heater.WaterHeaterEntityFeature.ON_OFF) ): @@ -742,7 +742,8 @@ class MediaPlayerCapabilities(AlexaEntity): and domain != "denonavr" ): inputs = AlexaEqualizerController.get_valid_inputs( - self.entity.attributes.get(media_player.const.ATTR_SOUND_MODE_LIST, []) + self.entity.attributes.get(media_player.const.ATTR_SOUND_MODE_LIST) + or [] ) if len(inputs) > 0: yield AlexaEqualizerController(self.entity) diff --git a/homeassistant/components/alexa/handlers.py b/homeassistant/components/alexa/handlers.py index 68702bc0533..463693f7da6 100644 --- a/homeassistant/components/alexa/handlers.py +++ b/homeassistant/components/alexa/handlers.py @@ -570,7 +570,7 @@ async def async_api_select_input( # Attempt to map the ALL UPPERCASE payload name to a source. # Strips trailing 1 to match single input devices. - source_list = entity.attributes.get(media_player.const.ATTR_INPUT_SOURCE_LIST, []) + source_list = entity.attributes.get(media_player.const.ATTR_INPUT_SOURCE_LIST) or [] for source in source_list: formatted_source = ( source.lower().replace("-", "").replace("_", "").replace(" ", "") @@ -987,7 +987,7 @@ async def async_api_set_thermostat_mode( ha_preset = next((k for k, v in API_THERMOSTAT_PRESETS.items() if v == mode), None) if ha_preset: - presets = entity.attributes.get(climate.ATTR_PRESET_MODES, []) + presets = entity.attributes.get(climate.ATTR_PRESET_MODES) or [] if ha_preset not in presets: msg = f"The requested thermostat mode {ha_preset} is not supported" @@ -997,7 +997,7 @@ async def async_api_set_thermostat_mode( data[climate.ATTR_PRESET_MODE] = ha_preset elif mode == "CUSTOM": - operation_list = entity.attributes.get(climate.ATTR_HVAC_MODES, []) + operation_list = entity.attributes.get(climate.ATTR_HVAC_MODES) or [] custom_mode = directive.payload["thermostatMode"]["customName"] custom_mode = next( (k for k, v in API_THERMOSTAT_MODES_CUSTOM.items() if v == custom_mode), @@ -1013,7 +1013,7 @@ async def async_api_set_thermostat_mode( data[climate.ATTR_HVAC_MODE] = custom_mode else: - operation_list = entity.attributes.get(climate.ATTR_HVAC_MODES, []) + operation_list = entity.attributes.get(climate.ATTR_HVAC_MODES) or [] ha_modes: dict[str, str] = { k: v for k, v in API_THERMOSTAT_MODES.items() if v == mode } From eeafb61b8f05c83890ed690a8cc45dfc829f0118 Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Tue, 23 Jan 2024 21:04:59 -0500 Subject: [PATCH 10/21] Reduce log level of ZHA endpoint handler init (#108749) * Reduce the log level of endpoint handler init failure to debug * Reduce log level in unit test --- homeassistant/components/zha/core/endpoint.py | 6 +++--- tests/components/zha/test_cluster_handlers.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/zha/core/endpoint.py b/homeassistant/components/zha/core/endpoint.py index 4dbfccf6f25..eb91ec96c59 100644 --- a/homeassistant/components/zha/core/endpoint.py +++ b/homeassistant/components/zha/core/endpoint.py @@ -199,11 +199,11 @@ class Endpoint: results = await gather(*tasks, return_exceptions=True) for cluster_handler, outcome in zip(cluster_handlers, results): if isinstance(outcome, Exception): - cluster_handler.warning( + cluster_handler.debug( "'%s' stage failed: %s", func_name, str(outcome), exc_info=outcome ) - continue - cluster_handler.debug("'%s' stage succeeded", func_name) + else: + cluster_handler.debug("'%s' stage succeeded", func_name) def async_new_entity( self, diff --git a/tests/components/zha/test_cluster_handlers.py b/tests/components/zha/test_cluster_handlers.py index 39f201e668e..46efe306b91 100644 --- a/tests/components/zha/test_cluster_handlers.py +++ b/tests/components/zha/test_cluster_handlers.py @@ -591,8 +591,8 @@ async def test_ep_cluster_handlers_configure(cluster_handler) -> None: assert ch.async_configure.call_count == 1 assert ch.async_configure.await_count == 1 - assert ch_3.warning.call_count == 2 - assert ch_5.warning.call_count == 2 + assert ch_3.debug.call_count == 2 + assert ch_5.debug.call_count == 2 async def test_poll_control_configure(poll_control_ch) -> None: From 12126ebfdafb659d3d980e4b577f2bd6eabacd23 Mon Sep 17 00:00:00 2001 From: Jan Bouwhuis Date: Wed, 24 Jan 2024 19:47:07 +0100 Subject: [PATCH 11/21] Fix google_assistant climate modes might be None (#108793) --- homeassistant/components/google_assistant/trait.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/google_assistant/trait.py b/homeassistant/components/google_assistant/trait.py index 9b8a95f0b4a..189d1354e26 100644 --- a/homeassistant/components/google_assistant/trait.py +++ b/homeassistant/components/google_assistant/trait.py @@ -1152,12 +1152,12 @@ class TemperatureSettingTrait(_Trait): modes = [] attrs = self.state.attributes - for mode in attrs.get(climate.ATTR_HVAC_MODES, []): + for mode in attrs.get(climate.ATTR_HVAC_MODES) or []: google_mode = self.hvac_to_google.get(mode) if google_mode and google_mode not in modes: modes.append(google_mode) - for preset in attrs.get(climate.ATTR_PRESET_MODES, []): + for preset in attrs.get(climate.ATTR_PRESET_MODES) or []: google_mode = self.preset_to_google.get(preset) if google_mode and google_mode not in modes: modes.append(google_mode) @@ -2094,9 +2094,10 @@ class InputSelectorTrait(_Trait): def sync_attributes(self): """Return mode attributes for a sync request.""" attrs = self.state.attributes + sourcelist: list[str] = attrs.get(media_player.ATTR_INPUT_SOURCE_LIST) or [] inputs = [ {"key": source, "names": [{"name_synonym": [source], "lang": "en"}]} - for source in attrs.get(media_player.ATTR_INPUT_SOURCE_LIST, []) + for source in sourcelist ] payload = {"availableInputs": inputs, "orderedInputs": True} From d220cb5102351b38ec37edc1527d832c135c55ff Mon Sep 17 00:00:00 2001 From: Jan Bouwhuis Date: Wed, 24 Jan 2024 22:14:15 +0100 Subject: [PATCH 12/21] Fix unhandled exception on humidifier intent when available_modes is None (#108802) --- homeassistant/components/humidifier/intent.py | 2 +- tests/components/humidifier/test_intent.py | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/humidifier/intent.py b/homeassistant/components/humidifier/intent.py index d949874cc67..103521aeb04 100644 --- a/homeassistant/components/humidifier/intent.py +++ b/homeassistant/components/humidifier/intent.py @@ -110,7 +110,7 @@ class SetModeHandler(intent.IntentHandler): intent.async_test_feature(state, HumidifierEntityFeature.MODES, "modes") mode = slots["mode"]["value"] - if mode not in state.attributes.get(ATTR_AVAILABLE_MODES, []): + if mode not in (state.attributes.get(ATTR_AVAILABLE_MODES) or []): raise intent.IntentHandleError( f"Entity {state.name} does not support {mode} mode" ) diff --git a/tests/components/humidifier/test_intent.py b/tests/components/humidifier/test_intent.py index cbdd5c3da26..d8c9f199f57 100644 --- a/tests/components/humidifier/test_intent.py +++ b/tests/components/humidifier/test_intent.py @@ -188,7 +188,10 @@ async def test_intent_set_mode_tests_feature(hass: HomeAssistant) -> None: assert len(mode_calls) == 0 -async def test_intent_set_unknown_mode(hass: HomeAssistant) -> None: +@pytest.mark.parametrize("available_modes", (["home", "away"], None)) +async def test_intent_set_unknown_mode( + hass: HomeAssistant, available_modes: list[str] | None +) -> None: """Test the set mode intent for unsupported mode.""" hass.states.async_set( "humidifier.bedroom_humidifier", @@ -196,8 +199,8 @@ async def test_intent_set_unknown_mode(hass: HomeAssistant) -> None: { ATTR_HUMIDITY: 40, ATTR_SUPPORTED_FEATURES: 1, - ATTR_AVAILABLE_MODES: ["home", "away"], - ATTR_MODE: "home", + ATTR_AVAILABLE_MODES: available_modes, + ATTR_MODE: None, }, ) mode_calls = async_mock_service(hass, DOMAIN, SERVICE_SET_MODE) From d697fd23b77a4e2f45cedb9df898f10ab98c52c3 Mon Sep 17 00:00:00 2001 From: Jan Bouwhuis Date: Wed, 24 Jan 2024 22:15:00 +0100 Subject: [PATCH 13/21] Fix processing supported color modes for emulated_hue (#108803) --- homeassistant/components/emulated_hue/hue_api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/emulated_hue/hue_api.py b/homeassistant/components/emulated_hue/hue_api.py index 0730eced60c..94ac97b6b36 100644 --- a/homeassistant/components/emulated_hue/hue_api.py +++ b/homeassistant/components/emulated_hue/hue_api.py @@ -386,7 +386,7 @@ class HueOneLightChangeView(HomeAssistantView): # Get the entity's supported features entity_features = entity.attributes.get(ATTR_SUPPORTED_FEATURES, 0) if entity.domain == light.DOMAIN: - color_modes = entity.attributes.get(light.ATTR_SUPPORTED_COLOR_MODES, []) + color_modes = entity.attributes.get(light.ATTR_SUPPORTED_COLOR_MODES) or [] # Parse the request parsed: dict[str, Any] = { @@ -765,7 +765,7 @@ def _entity_unique_id(entity_id: str) -> str: def state_to_json(config: Config, state: State) -> dict[str, Any]: """Convert an entity to its Hue bridge JSON representation.""" - color_modes = state.attributes.get(light.ATTR_SUPPORTED_COLOR_MODES, []) + color_modes = state.attributes.get(light.ATTR_SUPPORTED_COLOR_MODES) or [] unique_id = _entity_unique_id(state.entity_id) state_dict = get_entity_state_dict(config, state) From b66339dbfe49e7d79b9989821dbe5ced45c35339 Mon Sep 17 00:00:00 2001 From: TheJulianJES Date: Thu, 25 Jan 2024 14:45:11 +0100 Subject: [PATCH 14/21] Reduce log level for creating ZHA cluster handler (#108809) --- homeassistant/components/zha/core/endpoint.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/zha/core/endpoint.py b/homeassistant/components/zha/core/endpoint.py index eb91ec96c59..490a4e05ea2 100644 --- a/homeassistant/components/zha/core/endpoint.py +++ b/homeassistant/components/zha/core/endpoint.py @@ -132,7 +132,7 @@ class Endpoint: if not cluster_handler_class.matches(cluster, self): cluster_handler_class = ClusterHandler - _LOGGER.info( + _LOGGER.debug( "Creating cluster handler for cluster id: %s class: %s", cluster_id, cluster_handler_class, From 0532c4343a34906d197972368bef328895e480f5 Mon Sep 17 00:00:00 2001 From: Yuxin Wang Date: Sat, 27 Jan 2024 02:34:29 -0500 Subject: [PATCH 15/21] Fix stalls in config flow of APCUPSD (#108931) Fix deadlock in config flow of APCUPSD --- homeassistant/components/apcupsd/config_flow.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/homeassistant/components/apcupsd/config_flow.py b/homeassistant/components/apcupsd/config_flow.py index 57002d7a2b2..99c78fd5d33 100644 --- a/homeassistant/components/apcupsd/config_flow.py +++ b/homeassistant/components/apcupsd/config_flow.py @@ -52,9 +52,8 @@ class ConfigFlowHandler(ConfigFlow, domain=DOMAIN): # Test the connection to the host and get the current status for serial number. coordinator = APCUPSdCoordinator(self.hass, host, port) - await coordinator.async_request_refresh() - await self.hass.async_block_till_done() + if isinstance(coordinator.last_exception, (UpdateFailed, asyncio.TimeoutError)): errors = {"base": "cannot_connect"} return self.async_show_form( From 5903ec084b29f378a61957b033eccef7b6136a1b Mon Sep 17 00:00:00 2001 From: Joost Lekkerkerker Date: Sun, 28 Jan 2024 19:18:22 +0100 Subject: [PATCH 16/21] Add strings to Sensirion BLE (#109001) --- .../components/sensirion_ble/strings.json | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 homeassistant/components/sensirion_ble/strings.json diff --git a/homeassistant/components/sensirion_ble/strings.json b/homeassistant/components/sensirion_ble/strings.json new file mode 100644 index 00000000000..d1d544c2381 --- /dev/null +++ b/homeassistant/components/sensirion_ble/strings.json @@ -0,0 +1,22 @@ +{ + "config": { + "flow_title": "[%key:component::bluetooth::config::flow_title%]", + "step": { + "user": { + "description": "[%key:component::bluetooth::config::step::user::description%]", + "data": { + "address": "[%key:common::config_flow::data::device%]" + } + }, + "bluetooth_confirm": { + "description": "[%key:component::bluetooth::config::step::bluetooth_confirm::description%]" + } + }, + "abort": { + "not_supported": "Device not supported", + "no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]", + "already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]", + "already_configured": "[%key:common::config_flow::abort::already_configured_device%]" + } + } +} From 923259a8c63188cedf31a77b9479496155e95a11 Mon Sep 17 00:00:00 2001 From: Christopher Fenner <9592452+CFenner@users.noreply.github.com> Date: Sun, 28 Jan 2024 19:07:14 +0100 Subject: [PATCH 17/21] Fix entity naming for heatpump heatings in ViCare (#109013) Update strings.json --- homeassistant/components/vicare/strings.json | 28 ++++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/homeassistant/components/vicare/strings.json b/homeassistant/components/vicare/strings.json index 6c08215a9c1..87b5bb6cc14 100644 --- a/homeassistant/components/vicare/strings.json +++ b/homeassistant/components/vicare/strings.json @@ -141,52 +141,52 @@ "name": "Heating gas consumption this year" }, "gas_summary_consumption_heating_currentday": { - "name": "Heating gas consumption current day" + "name": "Heating gas consumption today" }, "gas_summary_consumption_heating_currentmonth": { - "name": "Heating gas consumption current month" + "name": "Heating gas consumption this month" }, "gas_summary_consumption_heating_currentyear": { - "name": "Heating gas consumption current year" + "name": "Heating gas consumption this year" }, "gas_summary_consumption_heating_lastsevendays": { "name": "Heating gas consumption last seven days" }, "hotwater_gas_summary_consumption_heating_currentday": { - "name": "DHW gas consumption current day" + "name": "DHW gas consumption today" }, "hotwater_gas_summary_consumption_heating_currentmonth": { - "name": "DHW gas consumption current month" + "name": "DHW gas consumption this month" }, "hotwater_gas_summary_consumption_heating_currentyear": { - "name": "DHW gas consumption current year" + "name": "DHW gas consumption this year" }, "hotwater_gas_summary_consumption_heating_lastsevendays": { "name": "DHW gas consumption last seven days" }, "energy_summary_consumption_heating_currentday": { - "name": "Energy consumption of gas heating current day" + "name": "Heating energy consumption today" }, "energy_summary_consumption_heating_currentmonth": { - "name": "Energy consumption of gas heating current month" + "name": "Heating energy consumption this month" }, "energy_summary_consumption_heating_currentyear": { - "name": "Energy consumption of gas heating current year" + "name": "Heating energy consumption this year" }, "energy_summary_consumption_heating_lastsevendays": { - "name": "Energy consumption of gas heating last seven days" + "name": "Heating energy consumption last seven days" }, "energy_dhw_summary_consumption_heating_currentday": { - "name": "Energy consumption of hot water gas heating current day" + "name": "DHW energy consumption today" }, "energy_dhw_summary_consumption_heating_currentmonth": { - "name": "Energy consumption of hot water gas heating current month" + "name": "DHW energy consumption this month" }, "energy_dhw_summary_consumption_heating_currentyear": { - "name": "Energy consumption of hot water gas heating current year" + "name": "DHW energy consumption this year" }, "energy_summary_dhw_consumption_heating_lastsevendays": { - "name": "Energy consumption of hot water gas heating last seven days" + "name": "DHW energy consumption last seven days" }, "power_production_current": { "name": "Power production current" From 8429a7979661098498df71d34076e6c71a50579b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 29 Jan 2024 12:15:18 -1000 Subject: [PATCH 18/21] Bump aiohttp to 3.9.3 (#109025) Co-authored-by: Joost Lekkerkerker --- homeassistant/package_constraints.txt | 2 +- pyproject.toml | 2 +- requirements.txt | 2 +- tests/components/websocket_api/test_auth.py | 2 +- tests/components/websocket_api/test_http.py | 6 +++--- tests/components/websocket_api/test_init.py | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index 821b6fdf141..9d030118dae 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -3,7 +3,7 @@ aiodiscover==1.6.0 aiohttp-fast-url-dispatcher==0.3.0 aiohttp-zlib-ng==0.1.3 -aiohttp==3.9.1 +aiohttp==3.9.3 aiohttp_cors==0.7.0 astral==2.2 async-upnp-client==0.38.1 diff --git a/pyproject.toml b/pyproject.toml index f678d14d214..82162ff02d6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,7 @@ classifiers = [ ] requires-python = ">=3.11.0" dependencies = [ - "aiohttp==3.9.1", + "aiohttp==3.9.3", "aiohttp_cors==0.7.0", "aiohttp-fast-url-dispatcher==0.3.0", "aiohttp-zlib-ng==0.1.3", diff --git a/requirements.txt b/requirements.txt index e1878a33584..eaf5b8a9e22 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ -c homeassistant/package_constraints.txt # Home Assistant Core -aiohttp==3.9.1 +aiohttp==3.9.3 aiohttp_cors==0.7.0 aiohttp-fast-url-dispatcher==0.3.0 aiohttp-zlib-ng==0.1.3 diff --git a/tests/components/websocket_api/test_auth.py b/tests/components/websocket_api/test_auth.py index d5ff879de78..dd18342abec 100644 --- a/tests/components/websocket_api/test_auth.py +++ b/tests/components/websocket_api/test_auth.py @@ -220,7 +220,7 @@ async def test_auth_close_after_revoke( await hass.auth.async_remove_refresh_token(refresh_token) msg = await websocket_client.receive() - assert msg.type == aiohttp.WSMsgType.CLOSE + assert msg.type == aiohttp.WSMsgType.CLOSED assert websocket_client.closed diff --git a/tests/components/websocket_api/test_http.py b/tests/components/websocket_api/test_http.py index e69b5629b63..f6723f0a592 100644 --- a/tests/components/websocket_api/test_http.py +++ b/tests/components/websocket_api/test_http.py @@ -42,7 +42,7 @@ async def test_pending_msg_overflow( for idx in range(10): await websocket_client.send_json({"id": idx + 1, "type": "ping"}) msg = await websocket_client.receive() - assert msg.type == WSMsgType.close + assert msg.type == WSMsgType.CLOSED async def test_cleanup_on_cancellation( @@ -248,7 +248,7 @@ async def test_pending_msg_peak( ) msg = await websocket_client.receive() - assert msg.type == WSMsgType.close + assert msg.type == WSMsgType.CLOSED assert "Client unable to keep up with pending messages" in caplog.text assert "Stayed over 5 for 5 seconds" in caplog.text assert "overload" in caplog.text @@ -296,7 +296,7 @@ async def test_pending_msg_peak_recovery( msg = await websocket_client.receive() assert msg.type == WSMsgType.TEXT msg = await websocket_client.receive() - assert msg.type == WSMsgType.close + assert msg.type == WSMsgType.CLOSED assert "Client unable to keep up with pending messages" not in caplog.text diff --git a/tests/components/websocket_api/test_init.py b/tests/components/websocket_api/test_init.py index 468b35fef51..c4c83925311 100644 --- a/tests/components/websocket_api/test_init.py +++ b/tests/components/websocket_api/test_init.py @@ -40,7 +40,7 @@ async def test_quiting_hass(hass: HomeAssistant, websocket_client) -> None: msg = await websocket_client.receive() - assert msg.type == WSMsgType.CLOSE + assert msg.type == WSMsgType.CLOSED async def test_unknown_command(websocket_client) -> None: From b7410fecb82cfab7c3f2c5e106fdf251be98bbb8 Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Mon, 29 Jan 2024 17:59:56 -0500 Subject: [PATCH 19/21] Bump ZHA dependency zigpy to 0.60.7 (#109082) --- homeassistant/components/zha/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/zha/manifest.json b/homeassistant/components/zha/manifest.json index de429b299c0..024fea9227a 100644 --- a/homeassistant/components/zha/manifest.json +++ b/homeassistant/components/zha/manifest.json @@ -26,7 +26,7 @@ "pyserial-asyncio==0.6", "zha-quirks==0.0.109", "zigpy-deconz==0.22.4", - "zigpy==0.60.6", + "zigpy==0.60.7", "zigpy-xbee==0.20.1", "zigpy-zigate==0.12.0", "zigpy-znp==0.12.1", diff --git a/requirements_all.txt b/requirements_all.txt index 99bde907caa..22d8e110fe7 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2888,7 +2888,7 @@ zigpy-zigate==0.12.0 zigpy-znp==0.12.1 # homeassistant.components.zha -zigpy==0.60.6 +zigpy==0.60.7 # homeassistant.components.zoneminder zm-py==0.5.4 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 3262ea26b88..cb89514bf1d 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -2187,7 +2187,7 @@ zigpy-zigate==0.12.0 zigpy-znp==0.12.1 # homeassistant.components.zha -zigpy==0.60.6 +zigpy==0.60.7 # homeassistant.components.zwave_js zwave-js-server-python==0.55.3 From 1c6c925a2b39d0942eaf3c34fdbca535854daccb Mon Sep 17 00:00:00 2001 From: Joost Lekkerkerker Date: Tue, 30 Jan 2024 10:07:23 +0100 Subject: [PATCH 20/21] Add missing abort message for Spotify (#109102) * Shield for unregistered Spotify users * Shield for unregistered Spotify users --- homeassistant/components/spotify/strings.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/spotify/strings.json b/homeassistant/components/spotify/strings.json index 02077cbdb43..e58d2098bde 100644 --- a/homeassistant/components/spotify/strings.json +++ b/homeassistant/components/spotify/strings.json @@ -17,7 +17,8 @@ "oauth_error": "[%key:common::config_flow::abort::oauth2_error%]", "oauth_timeout": "[%key:common::config_flow::abort::oauth2_timeout%]", "oauth_unauthorized": "[%key:common::config_flow::abort::oauth2_unauthorized%]", - "oauth_failed": "[%key:common::config_flow::abort::oauth2_failed%]" + "oauth_failed": "[%key:common::config_flow::abort::oauth2_failed%]", + "connection_error": "Could not fetch account information. Is the user registered in the Spotify Developer Dashboard?" }, "create_entry": { "default": "Successfully authenticated with Spotify." From 1dff998a25de8d3c8d8f80ecb493aa277fd0edca Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Tue, 30 Jan 2024 15:22:32 +0100 Subject: [PATCH 21/21] Bump version to 2024.1.6 --- homeassistant/const.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index f9d250c6732..0f483da47d8 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -16,7 +16,7 @@ from .helpers.deprecation import ( APPLICATION_NAME: Final = "HomeAssistant" MAJOR_VERSION: Final = 2024 MINOR_VERSION: Final = 1 -PATCH_VERSION: Final = "5" +PATCH_VERSION: Final = "6" __short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}" __version__: Final = f"{__short_version__}.{PATCH_VERSION}" REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 11, 0) diff --git a/pyproject.toml b/pyproject.toml index 82162ff02d6..f6d936fb637 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "homeassistant" -version = "2024.1.5" +version = "2024.1.6" license = {text = "Apache-2.0"} description = "Open-source home automation platform running on Python 3." readme = "README.rst"