Fix shelly delaying shutdown (#116346)

This commit is contained in:
J. Nick Koston 2024-04-28 11:19:38 -05:00 committed by Paulus Schoutsen
parent 88015986ad
commit 9445b84ab5
7 changed files with 69 additions and 45 deletions

View File

@ -361,7 +361,12 @@ class ShellyBlockCoordinator(ShellyCoordinatorBase[BlockDevice]):
) -> None:
"""Handle device update."""
if update_type is BlockUpdateType.ONLINE:
self.hass.async_create_task(self._async_device_connect(), eager_start=True)
self.entry.async_create_background_task(
self.hass,
self._async_device_connect(),
"block device online",
eager_start=True,
)
elif update_type is BlockUpdateType.COAP_PERIODIC:
self._push_update_failures = 0
ir.async_delete_issue(
@ -654,12 +659,24 @@ class ShellyRpcCoordinator(ShellyCoordinatorBase[RpcDevice]):
) -> None:
"""Handle device update."""
if update_type is RpcUpdateType.ONLINE:
self.hass.async_create_task(self._async_device_connect(), eager_start=True)
self.entry.async_create_background_task(
self.hass,
self._async_device_connect(),
"rpc device online",
eager_start=True,
)
elif update_type is RpcUpdateType.INITIALIZED:
self.hass.async_create_task(self._async_connected(), eager_start=True)
self.entry.async_create_background_task(
self.hass, self._async_connected(), "rpc device init", eager_start=True
)
self.async_set_updated_data(None)
elif update_type is RpcUpdateType.DISCONNECTED:
self.hass.async_create_task(self._async_disconnected(), eager_start=True)
self.entry.async_create_background_task(
self.hass,
self._async_disconnected(),
"rpc device disconnected",
eager_start=True,
)
elif update_type is RpcUpdateType.STATUS:
self.async_set_updated_data(None)
if self.sleep_period:
@ -673,7 +690,9 @@ class ShellyRpcCoordinator(ShellyCoordinatorBase[RpcDevice]):
self.device.subscribe_updates(self._async_handle_update)
if self.device.initialized:
# If we are already initialized, we are connected
self.hass.async_create_task(self._async_connected(), eager_start=True)
self.entry.async_create_task(
self.hass, self._async_connected(), eager_start=True
)
async def shutdown(self) -> None:
"""Shutdown the coordinator."""
@ -756,4 +775,9 @@ async def async_reconnect_soon(hass: HomeAssistant, entry: ConfigEntry) -> None:
and (entry_data := get_entry_data(hass).get(entry.entry_id))
and (coordinator := entry_data.rpc)
):
hass.async_create_task(coordinator.async_request_refresh(), eager_start=True)
entry.async_create_background_task(
hass,
coordinator.async_request_refresh(),
"reconnect soon",
eager_start=True,
)

View File

@ -145,7 +145,7 @@ async def test_block_sleeping_binary_sensor(
# Make device online
mock_block_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert hass.states.get(entity_id).state == STATE_OFF
@ -181,7 +181,7 @@ async def test_block_restored_sleeping_binary_sensor(
# Make device online
monkeypatch.setattr(mock_block_device, "initialized", True)
mock_block_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert hass.states.get(entity_id).state == STATE_OFF
@ -207,7 +207,7 @@ async def test_block_restored_sleeping_binary_sensor_no_last_state(
# Make device online
monkeypatch.setattr(mock_block_device, "initialized", True)
mock_block_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert hass.states.get(entity_id).state == STATE_OFF
@ -275,7 +275,7 @@ async def test_rpc_sleeping_binary_sensor(
# Make device online
mock_rpc_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert hass.states.get(entity_id).state == STATE_OFF
@ -346,7 +346,7 @@ async def test_rpc_restored_sleeping_binary_sensor_no_last_state(
# Make device online
monkeypatch.setattr(mock_rpc_device, "initialized", True)
mock_rpc_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
# Mock update
mock_rpc_device.mock_update()

View File

@ -70,7 +70,7 @@ async def test_climate_hvac_mode(
# Make device online
mock_block_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
# Test initial hvac mode - off
state = hass.states.get(ENTITY_ID)
@ -131,7 +131,7 @@ async def test_climate_set_temperature(
# Make device online
mock_block_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
state = hass.states.get(ENTITY_ID)
assert state.state == HVACMode.OFF
@ -198,7 +198,7 @@ async def test_climate_set_preset_mode(
# Make device online
mock_block_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
state = hass.states.get(ENTITY_ID)
assert state.attributes[ATTR_PRESET_MODE] == PRESET_NONE
@ -284,7 +284,7 @@ async def test_block_restored_climate(
# Make device online
monkeypatch.setattr(mock_block_device, "initialized", True)
mock_block_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert hass.states.get(entity_id).state == HVACMode.OFF
assert hass.states.get(entity_id).attributes.get("temperature") == 4.0
@ -355,7 +355,7 @@ async def test_block_restored_climate_us_customery(
monkeypatch.setattr(mock_block_device.blocks[SENSOR_BLOCK_ID], "targetTemp", 4.0)
monkeypatch.setattr(mock_block_device.blocks[SENSOR_BLOCK_ID], "temp", 18.2)
mock_block_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert hass.states.get(entity_id).state == HVACMode.OFF
assert hass.states.get(entity_id).attributes.get("temperature") == 39
@ -457,7 +457,7 @@ async def test_block_set_mode_connection_error(
# Make device online
mock_block_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
with pytest.raises(HomeAssistantError):
await hass.services.async_call(
@ -482,7 +482,7 @@ async def test_block_set_mode_auth_error(
# Make device online
mock_block_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert entry.state is ConfigEntryState.LOADED
@ -540,7 +540,7 @@ async def test_block_restored_climate_auth_error(
return_value={}, side_effect=InvalidAuthError
)
mock_block_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert entry.state is ConfigEntryState.LOADED
@ -567,7 +567,7 @@ async def test_device_not_calibrated(
# Make device online
mock_block_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
mock_status = MOCK_STATUS_COAP.copy()
mock_status["calibrated"] = False

View File

@ -224,7 +224,7 @@ async def test_block_sleeping_device_firmware_unsupported(
# Make device online
mock_block_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert entry.state is ConfigEntryState.LOADED
assert (
@ -299,7 +299,7 @@ async def test_block_sleeping_device_no_periodic_updates(
# Make device online
mock_block_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert get_entity_state(hass, entity_id) == "22.1"
@ -542,7 +542,7 @@ async def test_rpc_update_entry_sleep_period(
# Make device online
mock_rpc_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert entry.data["sleep_period"] == 600
@ -550,7 +550,7 @@ async def test_rpc_update_entry_sleep_period(
monkeypatch.setitem(mock_rpc_device.status["sys"], "wakeup_period", 3600)
freezer.tick(timedelta(seconds=600 * SLEEP_PERIOD_MULTIPLIER))
async_fire_time_changed(hass)
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert entry.data["sleep_period"] == 3600
@ -575,14 +575,14 @@ async def test_rpc_sleeping_device_no_periodic_updates(
# Make device online
mock_rpc_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert get_entity_state(hass, entity_id) == "22.9"
# Move time to generate polling
freezer.tick(timedelta(seconds=SLEEP_PERIOD_MULTIPLIER * 1000))
async_fire_time_changed(hass)
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert get_entity_state(hass, entity_id) is STATE_UNAVAILABLE
@ -599,7 +599,7 @@ async def test_rpc_sleeping_device_firmware_unsupported(
# Make device online
mock_rpc_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert entry.state is ConfigEntryState.LOADED
assert (
@ -765,7 +765,7 @@ async def test_rpc_update_entry_fw_ver(
# Make device online
mock_rpc_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert entry.unique_id
device = dev_reg.async_get_device(

View File

@ -44,7 +44,7 @@ async def test_block_number_update(
# Make device online
mock_block_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert hass.states.get(entity_id).state == "50"
@ -99,7 +99,7 @@ async def test_block_restored_number(
# Make device online
monkeypatch.setattr(mock_block_device, "initialized", True)
mock_block_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert hass.states.get(entity_id).state == "50"
@ -136,7 +136,7 @@ async def test_block_restored_number_no_last_state(
# Make device online
monkeypatch.setattr(mock_block_device, "initialized", True)
mock_block_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert hass.states.get(entity_id).state == "50"
@ -156,7 +156,7 @@ async def test_block_number_set_value(
# Make device online
mock_block_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
mock_block_device.reset_mock()
await hass.services.async_call(
@ -217,7 +217,7 @@ async def test_block_set_value_auth_error(
# Make device online
mock_block_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert entry.state is ConfigEntryState.LOADED

View File

@ -165,7 +165,7 @@ async def test_block_sleeping_sensor(
# Make device online
mock_block_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert hass.states.get(entity_id).state == "22.1"
@ -207,7 +207,7 @@ async def test_block_restored_sleeping_sensor(
# Make device online
monkeypatch.setattr(mock_block_device, "initialized", True)
mock_block_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert hass.states.get(entity_id).state == "22.1"
@ -233,7 +233,7 @@ async def test_block_restored_sleeping_sensor_no_last_state(
# Make device online
monkeypatch.setattr(mock_block_device, "initialized", True)
mock_block_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert hass.states.get(entity_id).state == "22.1"
@ -306,7 +306,7 @@ async def test_block_not_matched_restored_sleeping_sensor(
)
monkeypatch.setattr(mock_block_device, "initialized", True)
mock_block_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert hass.states.get(entity_id).state == "20.4"
@ -464,7 +464,7 @@ async def test_rpc_sleeping_sensor(
# Make device online
mock_rpc_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert hass.states.get(entity_id).state == "22.9"
@ -503,7 +503,7 @@ async def test_rpc_restored_sleeping_sensor(
# Make device online
monkeypatch.setattr(mock_rpc_device, "initialized", True)
mock_rpc_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
# Mock update
mock_rpc_device.mock_update()
@ -539,7 +539,7 @@ async def test_rpc_restored_sleeping_sensor_no_last_state(
# Make device online
monkeypatch.setattr(mock_rpc_device, "initialized", True)
mock_rpc_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
# Mock update
mock_rpc_device.mock_update()
@ -607,7 +607,7 @@ async def test_rpc_sleeping_update_entity_service(
# Make device online
mock_rpc_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
state = hass.states.get(entity_id)
assert state.state == "22.9"
@ -657,7 +657,7 @@ async def test_block_sleeping_update_entity_service(
# Make device online
mock_block_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
assert hass.states.get(entity_id).state == "22.1"

View File

@ -352,7 +352,7 @@ async def test_rpc_sleeping_update(
# Make device online
mock_rpc_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
state = hass.states.get(entity_id)
assert state.state == STATE_ON
@ -413,7 +413,7 @@ async def test_rpc_restored_sleeping_update(
# Make device online
monkeypatch.setattr(mock_rpc_device, "initialized", True)
mock_rpc_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
# Mock update
mock_rpc_device.mock_update()
@ -462,7 +462,7 @@ async def test_rpc_restored_sleeping_update_no_last_state(
# Make device online
monkeypatch.setattr(mock_rpc_device, "initialized", True)
mock_rpc_device.mock_online()
await hass.async_block_till_done()
await hass.async_block_till_done(wait_background_tasks=True)
# Mock update
mock_rpc_device.mock_update()