From f97f33fff78439543e01123e923c0fa11a223d91 Mon Sep 17 00:00:00 2001 From: Maciej Bieniek Date: Mon, 21 Aug 2023 20:27:36 +0000 Subject: [PATCH] Only create an issue if push updates fail 5 times in a row for Shelly gen1 devices (#98747) --- .../components/shelly/coordinator.py | 27 +++++++++++++------ tests/components/shelly/conftest.py | 8 ++++++ tests/components/shelly/test_coordinator.py | 22 +++++++-------- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/homeassistant/components/shelly/coordinator.py b/homeassistant/components/shelly/coordinator.py index 7829cd76567..d645b09799f 100644 --- a/homeassistant/components/shelly/coordinator.py +++ b/homeassistant/components/shelly/coordinator.py @@ -274,8 +274,23 @@ class ShellyBlockCoordinator(ShellyCoordinatorBase[BlockDevice]): except InvalidAuthError: self.entry.async_start_reauth(self.hass) else: + device_update_info(self.hass, self.device, self.entry) + + @callback + def _async_handle_update( + self, device_: BlockDevice, update_type: BlockUpdateType + ) -> None: + """Handle device update.""" + if update_type == BlockUpdateType.COAP_PERIODIC: + self._push_update_failures = 0 + ir.async_delete_issue( + self.hass, + DOMAIN, + PUSH_UPDATE_ISSUE_ID.format(unique=self.mac), + ) + elif update_type == BlockUpdateType.COAP_REPLY: self._push_update_failures += 1 - if self._push_update_failures > MAX_PUSH_UPDATE_FAILURES: + if self._push_update_failures == MAX_PUSH_UPDATE_FAILURES: LOGGER.debug( "Creating issue %s", PUSH_UPDATE_ISSUE_ID.format(unique=self.mac) ) @@ -293,13 +308,9 @@ class ShellyBlockCoordinator(ShellyCoordinatorBase[BlockDevice]): "ip_address": self.device.ip_address, }, ) - device_update_info(self.hass, self.device, self.entry) - - @callback - def _async_handle_update( - self, device_: BlockDevice, update_type: BlockUpdateType - ) -> None: - """Handle device update.""" + LOGGER.debug( + "Push update failures for %s: %s", self.name, self._push_update_failures + ) self.async_set_updated_data(None) def async_setup(self) -> None: diff --git a/tests/components/shelly/conftest.py b/tests/components/shelly/conftest.py index 2f33e76d336..de12adefaf1 100644 --- a/tests/components/shelly/conftest.py +++ b/tests/components/shelly/conftest.py @@ -251,6 +251,11 @@ async def mock_block_device(): {}, BlockUpdateType.COAP_PERIODIC ) + def update_reply(): + block_device_mock.return_value.subscribe_updates.call_args[0][0]( + {}, BlockUpdateType.COAP_REPLY + ) + device = Mock( spec=BlockDevice, blocks=MOCK_BLOCKS, @@ -265,6 +270,9 @@ async def mock_block_device(): type(device).name = PropertyMock(return_value="Test name") block_device_mock.return_value = device block_device_mock.return_value.mock_update = Mock(side_effect=update) + block_device_mock.return_value.mock_update_reply = Mock( + side_effect=update_reply + ) yield block_device_mock.return_value diff --git a/tests/components/shelly/test_coordinator.py b/tests/components/shelly/test_coordinator.py index eb546ce5835..5a8bb234f30 100644 --- a/tests/components/shelly/test_coordinator.py +++ b/tests/components/shelly/test_coordinator.py @@ -36,7 +36,6 @@ from . import ( mock_rest_update, register_entity, ) -from .conftest import MOCK_BLOCKS from tests.common import async_fire_time_changed @@ -259,24 +258,25 @@ async def test_block_device_push_updates_failure( """Test block device with push updates failure.""" issue_registry: ir.IssueRegistry = ir.async_get(hass) - monkeypatch.setattr( - mock_block_device, - "update", - AsyncMock(return_value=MOCK_BLOCKS), - ) await init_integration(hass, 1) - # Move time to force polling - for _ in range(MAX_PUSH_UPDATE_FAILURES + 1): - async_fire_time_changed( - hass, dt_util.utcnow() + timedelta(seconds=UPDATE_PERIOD_MULTIPLIER * 15) - ) + # Updates with COAP_REPLAY type should create an issue + for _ in range(MAX_PUSH_UPDATE_FAILURES): + mock_block_device.mock_update_reply() await hass.async_block_till_done() assert issue_registry.async_get_issue( domain=DOMAIN, issue_id=f"push_update_{MOCK_MAC}" ) + # An update with COAP_PERIODIC type should clear the issue + mock_block_device.mock_update() + await hass.async_block_till_done() + + assert not issue_registry.async_get_issue( + domain=DOMAIN, issue_id=f"push_update_{MOCK_MAC}" + ) + async def test_block_button_click_event( hass: HomeAssistant, mock_block_device, events, monkeypatch