From 97674cee88dd090e289d2bf8d9c61cf136a59dc0 Mon Sep 17 00:00:00 2001 From: Aidan Timson Date: Sat, 6 Jan 2024 09:06:23 +0000 Subject: [PATCH 1/6] Fix support for play/pause functionality in System Bridge (#103423) Fix support for play/pause functionality --- homeassistant/components/system_bridge/media_player.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/system_bridge/media_player.py b/homeassistant/components/system_bridge/media_player.py index ea9e8ab070d57..02670d36fe301 100644 --- a/homeassistant/components/system_bridge/media_player.py +++ b/homeassistant/components/system_bridge/media_player.py @@ -118,10 +118,8 @@ def supported_features(self) -> MediaPlayerEntityFeature: features |= MediaPlayerEntityFeature.PREVIOUS_TRACK if data.media.is_next_enabled: features |= MediaPlayerEntityFeature.NEXT_TRACK - if data.media.is_pause_enabled: - features |= MediaPlayerEntityFeature.PAUSE - if data.media.is_play_enabled: - features |= MediaPlayerEntityFeature.PLAY + if data.media.is_pause_enabled or data.media.is_play_enabled: + features |= MediaPlayerEntityFeature.PAUSE | MediaPlayerEntityFeature.PLAY if data.media.is_stop_enabled: features |= MediaPlayerEntityFeature.STOP From 5ff6284e0fc968172626f481add6c4b0b3920f5d Mon Sep 17 00:00:00 2001 From: Joost Lekkerkerker Date: Sat, 6 Jan 2024 10:50:06 +0100 Subject: [PATCH 2/6] Fix passing correct location id to streamlabs water (#107291) --- homeassistant/components/streamlabswater/__init__.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/homeassistant/components/streamlabswater/__init__.py b/homeassistant/components/streamlabswater/__init__.py index 82e8777a7e1ae..c3bbe5a96d4ee 100644 --- a/homeassistant/components/streamlabswater/__init__.py +++ b/homeassistant/components/streamlabswater/__init__.py @@ -107,9 +107,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: def set_away_mode(service: ServiceCall) -> None: """Set the StreamLabsWater Away Mode.""" away_mode = service.data.get(ATTR_AWAY_MODE) - location_id = ( - service.data.get(CONF_LOCATION_ID) or list(coordinator.data.values())[0] - ) + location_id = service.data.get(CONF_LOCATION_ID) or list(coordinator.data)[0] client.update_location(location_id, away_mode) hass.services.async_register( From 0dbb4105bc0c49ff52ea43ea29c334a2d2177b80 Mon Sep 17 00:00:00 2001 From: Shay Levy Date: Sat, 6 Jan 2024 01:32:04 +0200 Subject: [PATCH 3/6] Fix Shelly missing Gen value for older devices (#107294) --- homeassistant/components/shelly/config_flow.py | 7 ++++--- homeassistant/components/shelly/coordinator.py | 9 ++++++--- tests/components/shelly/__init__.py | 6 ++++-- tests/components/shelly/test_init.py | 8 ++++++++ 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/homeassistant/components/shelly/config_flow.py b/homeassistant/components/shelly/config_flow.py index 29daf05016370..59ae6eed1965a 100644 --- a/homeassistant/components/shelly/config_flow.py +++ b/homeassistant/components/shelly/config_flow.py @@ -36,6 +36,7 @@ from .utils import ( get_block_device_sleep_period, get_coap_context, + get_device_entry_gen, get_info_auth, get_info_gen, get_model_name, @@ -322,7 +323,7 @@ async def async_step_reauth_confirm( except (DeviceConnectionError, InvalidAuthError, FirmwareUnsupported): return self.async_abort(reason="reauth_unsuccessful") - if self.entry.data.get(CONF_GEN, 1) != 1: + if get_device_entry_gen(self.entry) != 1: user_input[CONF_USERNAME] = "admin" try: await validate_input(self.hass, host, info, user_input) @@ -335,7 +336,7 @@ async def async_step_reauth_confirm( await self.hass.config_entries.async_reload(self.entry.entry_id) return self.async_abort(reason="reauth_successful") - if self.entry.data.get(CONF_GEN, 1) in BLOCK_GENERATIONS: + if get_device_entry_gen(self.entry) in BLOCK_GENERATIONS: schema = { vol.Required(CONF_USERNAME): str, vol.Required(CONF_PASSWORD): str, @@ -364,7 +365,7 @@ def async_get_options_flow(config_entry: ConfigEntry) -> OptionsFlowHandler: def async_supports_options_flow(cls, config_entry: ConfigEntry) -> bool: """Return options flow support for this handler.""" return ( - config_entry.data.get(CONF_GEN) in RPC_GENERATIONS + get_device_entry_gen(config_entry) in RPC_GENERATIONS and not config_entry.data.get(CONF_SLEEP_PERIOD) and config_entry.data.get("model") != MODEL_WALL_DISPLAY ) diff --git a/homeassistant/components/shelly/coordinator.py b/homeassistant/components/shelly/coordinator.py index 77fa0bd2efd16..7f88cce1134b5 100644 --- a/homeassistant/components/shelly/coordinator.py +++ b/homeassistant/components/shelly/coordinator.py @@ -33,7 +33,6 @@ ATTR_GENERATION, BATTERY_DEVICES_WITH_PERMANENT_CONNECTION, CONF_BLE_SCANNER_MODE, - CONF_GEN, CONF_SLEEP_PERIOD, DATA_CONFIG_ENTRY, DOMAIN, @@ -58,7 +57,11 @@ UPDATE_PERIOD_MULTIPLIER, BLEScannerMode, ) -from .utils import get_rpc_device_wakeup_period, update_device_fw_info +from .utils import ( + get_device_entry_gen, + get_rpc_device_wakeup_period, + update_device_fw_info, +) _DeviceT = TypeVar("_DeviceT", bound="BlockDevice|RpcDevice") @@ -136,7 +139,7 @@ def async_setup(self) -> None: manufacturer="Shelly", model=aioshelly.const.MODEL_NAMES.get(self.model, self.model), sw_version=self.sw_version, - hw_version=f"gen{self.entry.data[CONF_GEN]} ({self.model})", + hw_version=f"gen{get_device_entry_gen(self.entry)} ({self.model})", configuration_url=f"http://{self.entry.data[CONF_HOST]}", ) self.device_id = device_entry.id diff --git a/tests/components/shelly/__init__.py b/tests/components/shelly/__init__.py index 0384e9255a38f..26040e1355779 100644 --- a/tests/components/shelly/__init__.py +++ b/tests/components/shelly/__init__.py @@ -12,6 +12,7 @@ import pytest from homeassistant.components.shelly.const import ( + CONF_GEN, CONF_SLEEP_PERIOD, DOMAIN, REST_SENSORS_UPDATE_INTERVAL, @@ -30,7 +31,7 @@ async def init_integration( hass: HomeAssistant, - gen: int, + gen: int | None, model=MODEL_25, sleep_period=0, options: dict[str, Any] | None = None, @@ -41,8 +42,9 @@ async def init_integration( CONF_HOST: "192.168.1.37", CONF_SLEEP_PERIOD: sleep_period, "model": model, - "gen": gen, } + if gen is not None: + data[CONF_GEN] = gen entry = MockConfigEntry( domain=DOMAIN, data=data, unique_id=MOCK_MAC, options=options diff --git a/tests/components/shelly/test_init.py b/tests/components/shelly/test_init.py index 8f6599b39e46e..643fc775cc424 100644 --- a/tests/components/shelly/test_init.py +++ b/tests/components/shelly/test_init.py @@ -301,3 +301,11 @@ async def test_no_attempt_to_stop_scanner_with_sleepy_devices( mock_rpc_device.mock_update() await hass.async_block_till_done() assert not mock_stop_scanner.call_count + + +async def test_entry_missing_gen(hass: HomeAssistant, mock_block_device) -> None: + """Test successful Gen1 device init when gen is missing in entry data.""" + entry = await init_integration(hass, None) + + assert entry.state is ConfigEntryState.LOADED + assert hass.states.get("switch.test_name_channel_1").state is STATE_ON From 5a01b55fd1b4f6fb08f95f31f5bb3a2da098426d Mon Sep 17 00:00:00 2001 From: Sid <27780930+autinerd@users.noreply.github.com> Date: Sat, 6 Jan 2024 11:18:32 +0100 Subject: [PATCH 4/6] enigma2: fix exception when device in deep sleep, fix previous track (#107296) enigma2: fix exception when device in deep sleep; previous track --- homeassistant/components/enigma2/media_player.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/enigma2/media_player.py b/homeassistant/components/enigma2/media_player.py index 432823d781bfe..e4283eeef9dba 100644 --- a/homeassistant/components/enigma2/media_player.py +++ b/homeassistant/components/enigma2/media_player.py @@ -1,6 +1,7 @@ """Support for Enigma2 media players.""" from __future__ import annotations +from aiohttp.client_exceptions import ClientConnectorError from openwebif.api import OpenWebIfDevice from openwebif.enums import RemoteControlCodes import voluptuous as vol @@ -20,6 +21,7 @@ CONF_USERNAME, ) from homeassistant.core import HomeAssistant +from homeassistant.exceptions import PlatformNotReady import homeassistant.helpers.config_validation as cv from homeassistant.helpers.config_validation import PLATFORM_SCHEMA from homeassistant.helpers.entity_platform import AddEntitiesCallback @@ -96,9 +98,13 @@ async def async_setup_platform( source_bouquet=config.get(CONF_SOURCE_BOUQUET), ) - async_add_entities( - [Enigma2Device(config[CONF_NAME], device, await device.get_about())] - ) + try: + about = await device.get_about() + except ClientConnectorError as err: + await device.close() + raise PlatformNotReady from err + + async_add_entities([Enigma2Device(config[CONF_NAME], device, about)]) class Enigma2Device(MediaPlayerEntity): @@ -169,8 +175,8 @@ async def async_media_next_track(self) -> None: await self._device.send_remote_control_action(RemoteControlCodes.CHANNEL_UP) async def async_media_previous_track(self) -> None: - """Send next track command.""" - self._device.send_remote_control_action(RemoteControlCodes.CHANNEL_DOWN) + """Send previous track command.""" + await self._device.send_remote_control_action(RemoteControlCodes.CHANNEL_DOWN) async def async_mute_volume(self, mute: bool) -> None: """Mute or unmute.""" From 003d2be47754d31351918e956e7d5b72c2a5fbdf Mon Sep 17 00:00:00 2001 From: "David F. Mulcahey" Date: Fri, 5 Jan 2024 16:53:43 -0500 Subject: [PATCH 5/6] Fix assertion error when unloading ZHA with pollable entities (#107311) --- homeassistant/components/zha/sensor.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/zha/sensor.py b/homeassistant/components/zha/sensor.py index 027e710e30c76..ea5d09dd6f4d5 100644 --- a/homeassistant/components/zha/sensor.py +++ b/homeassistant/components/zha/sensor.py @@ -216,9 +216,9 @@ async def async_added_to_hass(self) -> None: async def async_will_remove_from_hass(self) -> None: """Disconnect entity object when removed.""" - assert self._cancel_refresh_handle - self._cancel_refresh_handle() - self._cancel_refresh_handle = None + if self._cancel_refresh_handle is not None: + self._cancel_refresh_handle() + self._cancel_refresh_handle = None self.debug("stopped polling during device removal") await super().async_will_remove_from_hass() From cab833160dcbeaf4f23c89595f3851dac98840f0 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Sat, 6 Jan 2024 12:25:05 +0100 Subject: [PATCH 6/6] Bump version to 2024.1.2 --- 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 cea73ec243b47..c91743e7ba972 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -16,7 +16,7 @@ APPLICATION_NAME: Final = "HomeAssistant" MAJOR_VERSION: Final = 2024 MINOR_VERSION: Final = 1 -PATCH_VERSION: Final = "1" +PATCH_VERSION: Final = "2" __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 3bec11ced3bbe..bbf45725716ef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "homeassistant" -version = "2024.1.1" +version = "2024.1.2" license = {text = "Apache-2.0"} description = "Open-source home automation platform running on Python 3." readme = "README.rst"