diff --git a/CHANGELOG.md b/CHANGELOG.md index b36a63b7a..37aba796e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ Versions from 0.40 and up +## Ongoing + +- Revert exceptions-move in coordinator.py, line up with Core Plugwise via PR [#990](https://github.com/plugwise/plugwise-beta/pull/990) + ## v0.62.1 - Implement Core PR's [#158901](https://github.com/home-assistant/core/pull/158901) and [#158094](https://github.com/home-assistant/core/pull/158094) diff --git a/custom_components/plugwise/coordinator.py b/custom_components/plugwise/coordinator.py index 8896f024a..363a9083f 100644 --- a/custom_components/plugwise/coordinator.py +++ b/custom_components/plugwise/coordinator.py @@ -87,34 +87,7 @@ async def _connect(self) -> None: A Version object is received when the connection succeeds. """ - try: - version = await self.api.connect() - except ConnectionFailedError as err: - raise UpdateFailed( - translation_domain=DOMAIN, - translation_key="failed_to_connect", - ) from err - except InvalidAuthentication as err: - raise ConfigEntryError( - translation_domain=DOMAIN, - translation_key="authentication_failed", - ) from err - except InvalidSetupError as err: - raise ConfigEntryError( - translation_domain=DOMAIN, - translation_key="invalid_setup", - ) from err - except (InvalidXMLError, ResponseError) as err: - raise UpdateFailed( - translation_domain=DOMAIN, - translation_key="invalid_xml_data", - ) from err - except UnsupportedDeviceError as err: - raise ConfigEntryError( - translation_domain=DOMAIN, - translation_key="unsupported_firmware", - ) from err - + version = await self.api.connect() self._connected = isinstance(version, Version) if self._connected: self.update_interval = DEFAULT_SCAN_INTERVAL.get( @@ -125,7 +98,7 @@ async def _connect(self) -> None: seconds=int(custom_time) ) # pragma: no cover # pw-beta options - LOGGER.debug("DUC update interval: %s", self.update_interval) # pw-beta options + LOGGER.debug("DUC update interval: %s", self.update_interval) # pw-beta options async def _async_setup(self) -> None: """Initialize the update_data process.""" @@ -142,15 +115,40 @@ async def _async_setup(self) -> None: async def _async_update_data(self) -> dict[str, GwEntityData]: """Fetch data from Plugwise.""" - if not self._connected: - await self._connect() try: + if not self._connected: + await self._connect() data = await self.api.async_update() + except ConnectionFailedError as err: + raise UpdateFailed( + translation_domain=DOMAIN, + translation_key="failed_to_connect", + ) from err + except InvalidAuthentication as err: + raise ConfigEntryError( + translation_domain=DOMAIN, + translation_key="authentication_failed", + ) from err + except InvalidSetupError as err: + raise ConfigEntryError( + translation_domain=DOMAIN, + translation_key="invalid_setup", + ) from err + except (InvalidXMLError, ResponseError) as err: + raise UpdateFailed( + translation_domain=DOMAIN, + translation_key="response_error", + ) from err except PlugwiseError as err: raise UpdateFailed( translation_domain=DOMAIN, translation_key="data_incomplete_or_missing", ) from err + except UnsupportedDeviceError as err: + raise ConfigEntryError( + translation_domain=DOMAIN, + translation_key="unsupported_firmware", + ) from err await self._async_add_remove_devices(data) LOGGER.debug("%s data: %s", self.api.smile.name, data) diff --git a/custom_components/plugwise/strings.json b/custom_components/plugwise/strings.json index abe61ab69..d7434a97c 100644 --- a/custom_components/plugwise/strings.json +++ b/custom_components/plugwise/strings.json @@ -42,7 +42,7 @@ "invalid_setup": "Add your Adam instead of your Anna, see the documentation", "network_down": "Plugwise Zigbee network is down", "network_timeout": "Network communication timeout", - "response_error": "Invalid XML data, or error indication received", + "response_error": "Invalid XML data, or error indication received from the Plugwise Adam/Smile/Stretch", "stick_init": "Initialization of Plugwise USB-stick failed", "unknown": "Unknown error!", "unsupported": "Device with unsupported firmware" @@ -323,7 +323,10 @@ "failed_to_connect": { "message": "Failed to connect" }, - "invalid_xml_data": { + "invalid_setup": { + "message": "Add your Adam instead of your Anna, see the documentation" + }, + "response_error": { "message": "Invalid XML data, or error indication received from the Plugwise Adam/Smile/Stretch" }, "set_schedule_first": { diff --git a/custom_components/plugwise/translations/en.json b/custom_components/plugwise/translations/en.json index 8d2f26d06..388ad0073 100644 --- a/custom_components/plugwise/translations/en.json +++ b/custom_components/plugwise/translations/en.json @@ -12,7 +12,7 @@ "invalid_setup": "Add your Adam instead of your Anna, see the documentation", "network_down": "Plugwise Zigbee network is down", "network_timeout": "Network communication timeout", - "response_error": "Invalid XML data, or error indication received", + "response_error": "Invalid XML data, or error indication received from the Plugwise Adam/Smile/Stretch", "stick_init": "Initialization of Plugwise USB-stick failed", "unknown": "Unknown error!", "unsupported": "Device with unsupported firmware" @@ -306,7 +306,10 @@ "failed_to_connect": { "message": "Failed to connect" }, - "invalid_xml_data": { + "invalid_setup": { + "message": "Add your Adam instead of your Anna, see the documentation" + }, + "response_error": { "message": "Invalid XML data, or error indication received from the Plugwise Adam/Smile/Stretch" }, "set_schedule_first": { diff --git a/custom_components/plugwise/translations/nl.json b/custom_components/plugwise/translations/nl.json index 5cd6e90b2..696fd05cc 100644 --- a/custom_components/plugwise/translations/nl.json +++ b/custom_components/plugwise/translations/nl.json @@ -42,7 +42,7 @@ "invalid_setup": "Voeg je Adam toe in plaats van je Anna, lees de documentatie", "network_down": "Plugwise Zigbee netwerk is onbereikbaar", "network_timeout": "Network communicatie timeout", - "response_error": "Ongeldige XML data, of error-indicatie ontvangen", + "response_error": "Ongeldige XML data, of foutmelding ontvangen van de Plugwise Adam/Smile/Stretch", "stick_init": "Initaliseren van USB-stick mislukt", "unknown": "Onbekende fout!", "unsupported": "Apparaat met onbekende firmware" @@ -321,7 +321,10 @@ "failed_to_connect": { "message": "Verbinden mislukt" }, - "invalid_xml_data": { + "invalid_setup": { + "message": "Voeg je Adam toe in plaats van je Anna, lees de documentatie" + }, + "response_error": { "message": "Ongeldige XML data, of foutmelding ontvangen van de Plugwise Adam/Smile/Stretch" }, "set_schedule_first": { diff --git a/pyproject.toml b/pyproject.toml index d125fcb03..93262f475 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "plugwise-beta" -version = "0.62.1" +version = "0.62.2" description = "Plugwise beta custom-component" readme = "README.md" requires-python = ">=3.13" diff --git a/tests/components/plugwise/snapshots/test_select.ambr b/tests/components/plugwise/snapshots/test_select.ambr index c2680f7bc..90ace520e 100644 --- a/tests/components/plugwise/snapshots/test_select.ambr +++ b/tests/components/plugwise/snapshots/test_select.ambr @@ -141,7 +141,7 @@ 'device_id': , 'disabled_by': None, 'domain': 'select', - 'entity_category': , + 'entity_category': None, 'entity_id': 'select.bathroom_thermostat_schedule', 'has_entity_name': True, 'hidden_by': None, @@ -263,7 +263,7 @@ 'device_id': , 'disabled_by': None, 'domain': 'select', - 'entity_category': , + 'entity_category': None, 'entity_id': 'select.living_room_thermostat_schedule', 'has_entity_name': True, 'hidden_by': None, @@ -386,7 +386,7 @@ 'device_id': , 'disabled_by': None, 'domain': 'select', - 'entity_category': , + 'entity_category': None, 'entity_id': 'select.badkamer_thermostat_schedule', 'has_entity_name': True, 'hidden_by': None, @@ -451,7 +451,7 @@ 'device_id': , 'disabled_by': None, 'domain': 'select', - 'entity_category': , + 'entity_category': None, 'entity_id': 'select.bios_thermostat_schedule', 'has_entity_name': True, 'hidden_by': None, @@ -516,7 +516,7 @@ 'device_id': , 'disabled_by': None, 'domain': 'select', - 'entity_category': , + 'entity_category': None, 'entity_id': 'select.jessie_thermostat_schedule', 'has_entity_name': True, 'hidden_by': None, @@ -581,7 +581,7 @@ 'device_id': , 'disabled_by': None, 'domain': 'select', - 'entity_category': , + 'entity_category': None, 'entity_id': 'select.woonkamer_thermostat_schedule', 'has_entity_name': True, 'hidden_by': None, diff --git a/tests/components/plugwise/test_init.py b/tests/components/plugwise/test_init.py index 7d0883774..035c52038 100644 --- a/tests/components/plugwise/test_init.py +++ b/tests/components/plugwise/test_init.py @@ -15,7 +15,6 @@ from freezegun.api import FrozenDateTimeFactory from homeassistant.components.plugwise.const import DOMAIN -from homeassistant.components.plugwise.coordinator import PlugwiseDataUpdateCoordinator from homeassistant.config_entries import ConfigEntryState from homeassistant.const import ( CONF_HOST, @@ -27,9 +26,7 @@ Platform, ) from homeassistant.core import HomeAssistant -from homeassistant.exceptions import ConfigEntryError from homeassistant.helpers import device_registry as dr, entity_registry as er -from homeassistant.helpers.update_coordinator import UpdateFailed from homeassistant.setup import async_setup_component from tests.common import MockConfigEntry, async_fire_time_changed @@ -104,7 +101,7 @@ async def test_gateway_config_entry_not_ready( mock_smile_anna: MagicMock, side_effect: Exception, ) -> None: - """Test the Plugwise configuration entry not ready.""" + """Test the Plugwise config-entry not being ready.""" mock_smile_anna.async_update.side_effect = side_effect mock_config_entry.add_to_hass(hass) @@ -118,14 +115,15 @@ async def test_gateway_config_entry_not_ready( @pytest.mark.parametrize("chosen_env", ["anna_heatpump_heating"], indirect=True) @pytest.mark.parametrize("cooling_present", [True], indirect=True) @pytest.mark.parametrize( - ("side_effect", "expected_raise"), + ("side_effect", "entry_state"), [ - (ConnectionFailedError, UpdateFailed), - (InvalidAuthentication, ConfigEntryError), - (InvalidSetupError, ConfigEntryError), - (InvalidXMLError, UpdateFailed), - (ResponseError, UpdateFailed), - (UnsupportedDeviceError, ConfigEntryError), + (ConnectionFailedError, ConfigEntryState.SETUP_RETRY), + (InvalidAuthentication, ConfigEntryState.SETUP_ERROR), + (InvalidSetupError, ConfigEntryState.SETUP_ERROR), + (InvalidXMLError, ConfigEntryState.SETUP_RETRY), + (ResponseError, ConfigEntryState.SETUP_RETRY), + (PlugwiseError, ConfigEntryState.SETUP_RETRY), + (UnsupportedDeviceError, ConfigEntryState.SETUP_ERROR), ], ) async def test_coordinator_connect_exceptions( @@ -133,17 +131,17 @@ async def test_coordinator_connect_exceptions( mock_config_entry: MockConfigEntry, mock_smile_anna: MagicMock, side_effect: Exception, - expected_raise: Exception, + entry_state: ConfigEntryState, ) -> None: """Ensure _connect raises translated errors.""" mock_smile_anna.connect.side_effect = side_effect - coordinator = PlugwiseDataUpdateCoordinator( - hass, - cooldown=0, - config_entry=mock_config_entry, - ) - with pytest.raises(expected_raise): - await coordinator._connect() + + mock_config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(mock_config_entry.entry_id) + await hass.async_block_till_done() + + assert len(mock_smile_anna.connect.mock_calls) == 1 + assert mock_config_entry.state is entry_state @pytest.mark.parametrize("chosen_env", ["p1v4_442_single"], indirect=True) @@ -360,9 +358,6 @@ async def test_delete_removed_device( ) -> None: """Test device removal at integration init.""" data = mock_smile_adam_heat_cool.async_update.return_value - mock_config_entry.add_to_hass(hass) - assert await async_setup_component(hass, DOMAIN, {}) - await hass.async_block_till_done() item_list: list[str] = [] for device_entry in device_registry.devices.values():