Fix shelly sleepy entities never being created (#124547)
This commit is contained in:
parent
0628f96713
commit
be206156b0
8 changed files with 132 additions and 33 deletions
|
@ -21,6 +21,7 @@ from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
|||
from homeassistant.helpers import (
|
||||
config_validation as cv,
|
||||
device_registry as dr,
|
||||
entity_registry as er,
|
||||
issue_registry as ir,
|
||||
)
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
|
@ -192,8 +193,15 @@ async def _async_setup_block_entry(
|
|||
await hass.config_entries.async_forward_entry_setups(
|
||||
entry, runtime_data.platforms
|
||||
)
|
||||
elif sleep_period is None or device_entry is None:
|
||||
elif (
|
||||
sleep_period is None
|
||||
or device_entry is None
|
||||
or not er.async_entries_for_device(er.async_get(hass), device_entry.id)
|
||||
):
|
||||
# Need to get sleep info or first time sleeping device setup, wait for device
|
||||
# If there are no entities for the device, it means we added the device, but
|
||||
# Home Assistant was restarted before the device was online. In this case we
|
||||
# cannot restore the entities, so we need to wait for the device to be online.
|
||||
LOGGER.debug(
|
||||
"Setup for device %s will resume when device is online", entry.title
|
||||
)
|
||||
|
@ -268,8 +276,15 @@ async def _async_setup_rpc_entry(hass: HomeAssistant, entry: ShellyConfigEntry)
|
|||
await hass.config_entries.async_forward_entry_setups(
|
||||
entry, runtime_data.platforms
|
||||
)
|
||||
elif sleep_period is None or device_entry is None:
|
||||
elif (
|
||||
sleep_period is None
|
||||
or device_entry is None
|
||||
or not er.async_entries_for_device(er.async_get(hass), device_entry.id)
|
||||
):
|
||||
# Need to get sleep info or first time sleeping device setup, wait for device
|
||||
# If there are no entities for the device, it means we added the device, but
|
||||
# Home Assistant was restarted before the device was online. In this case we
|
||||
# cannot restore the entities, so we need to wait for the device to be online.
|
||||
LOGGER.debug(
|
||||
"Setup for device %s will resume when device is online", entry.title
|
||||
)
|
||||
|
|
|
@ -169,9 +169,14 @@ async def test_block_restored_sleeping_binary_sensor(
|
|||
) -> None:
|
||||
"""Test block restored sleeping binary sensor."""
|
||||
entry = await init_integration(hass, 1, sleep_period=1000, skip_setup=True)
|
||||
register_device(device_registry, entry)
|
||||
device = register_device(device_registry, entry)
|
||||
entity_id = register_entity(
|
||||
hass, BINARY_SENSOR_DOMAIN, "test_name_motion", "sensor_0-motion", entry
|
||||
hass,
|
||||
BINARY_SENSOR_DOMAIN,
|
||||
"test_name_motion",
|
||||
"sensor_0-motion",
|
||||
entry,
|
||||
device_id=device.id,
|
||||
)
|
||||
mock_restore_cache(hass, [State(entity_id, STATE_ON)])
|
||||
monkeypatch.setattr(mock_block_device, "initialized", False)
|
||||
|
@ -196,9 +201,14 @@ async def test_block_restored_sleeping_binary_sensor_no_last_state(
|
|||
) -> None:
|
||||
"""Test block restored sleeping binary sensor missing last state."""
|
||||
entry = await init_integration(hass, 1, sleep_period=1000, skip_setup=True)
|
||||
register_device(device_registry, entry)
|
||||
device = register_device(device_registry, entry)
|
||||
entity_id = register_entity(
|
||||
hass, BINARY_SENSOR_DOMAIN, "test_name_motion", "sensor_0-motion", entry
|
||||
hass,
|
||||
BINARY_SENSOR_DOMAIN,
|
||||
"test_name_motion",
|
||||
"sensor_0-motion",
|
||||
entry,
|
||||
device_id=device.id,
|
||||
)
|
||||
monkeypatch.setattr(mock_block_device, "initialized", False)
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
|
@ -305,9 +315,14 @@ async def test_rpc_restored_sleeping_binary_sensor(
|
|||
) -> None:
|
||||
"""Test RPC restored binary sensor."""
|
||||
entry = await init_integration(hass, 2, sleep_period=1000, skip_setup=True)
|
||||
register_device(device_registry, entry)
|
||||
device = register_device(device_registry, entry)
|
||||
entity_id = register_entity(
|
||||
hass, BINARY_SENSOR_DOMAIN, "test_name_cloud", "cloud-cloud", entry
|
||||
hass,
|
||||
BINARY_SENSOR_DOMAIN,
|
||||
"test_name_cloud",
|
||||
"cloud-cloud",
|
||||
entry,
|
||||
device_id=device.id,
|
||||
)
|
||||
|
||||
mock_restore_cache(hass, [State(entity_id, STATE_ON)])
|
||||
|
@ -334,9 +349,14 @@ async def test_rpc_restored_sleeping_binary_sensor_no_last_state(
|
|||
) -> None:
|
||||
"""Test RPC restored sleeping binary sensor missing last state."""
|
||||
entry = await init_integration(hass, 2, sleep_period=1000, skip_setup=True)
|
||||
register_device(device_registry, entry)
|
||||
device = register_device(device_registry, entry)
|
||||
entity_id = register_entity(
|
||||
hass, BINARY_SENSOR_DOMAIN, "test_name_cloud", "cloud-cloud", entry
|
||||
hass,
|
||||
BINARY_SENSOR_DOMAIN,
|
||||
"test_name_cloud",
|
||||
"cloud-cloud",
|
||||
entry,
|
||||
device_id=device.id,
|
||||
)
|
||||
|
||||
monkeypatch.setattr(mock_rpc_device, "initialized", False)
|
||||
|
|
|
@ -254,13 +254,14 @@ async def test_block_restored_climate(
|
|||
monkeypatch.setattr(mock_block_device.blocks[DEVICE_BLOCK_ID], "valveError", 0)
|
||||
monkeypatch.delattr(mock_block_device.blocks[EMETER_BLOCK_ID], "targetTemp")
|
||||
entry = await init_integration(hass, 1, sleep_period=1000, skip_setup=True)
|
||||
register_device(device_registry, entry)
|
||||
device = register_device(device_registry, entry)
|
||||
entity_id = register_entity(
|
||||
hass,
|
||||
CLIMATE_DOMAIN,
|
||||
"test_name",
|
||||
"sensor_0",
|
||||
entry,
|
||||
device_id=device.id,
|
||||
)
|
||||
attrs = {"current_temperature": 20.5, "temperature": 4.0}
|
||||
extra_data = {"last_target_temp": 22.0}
|
||||
|
@ -321,13 +322,14 @@ async def test_block_restored_climate_us_customery(
|
|||
monkeypatch.setattr(mock_block_device.blocks[DEVICE_BLOCK_ID], "valveError", 0)
|
||||
monkeypatch.delattr(mock_block_device.blocks[EMETER_BLOCK_ID], "targetTemp")
|
||||
entry = await init_integration(hass, 1, sleep_period=1000, skip_setup=True)
|
||||
register_device(device_registry, entry)
|
||||
device = register_device(device_registry, entry)
|
||||
entity_id = register_entity(
|
||||
hass,
|
||||
CLIMATE_DOMAIN,
|
||||
"test_name",
|
||||
"sensor_0",
|
||||
entry,
|
||||
device_id=device.id,
|
||||
)
|
||||
attrs = {"current_temperature": 67, "temperature": 39}
|
||||
extra_data = {"last_target_temp": 10.0}
|
||||
|
@ -390,13 +392,14 @@ async def test_block_restored_climate_unavailable(
|
|||
monkeypatch.delattr(mock_block_device.blocks[DEVICE_BLOCK_ID], "targetTemp")
|
||||
monkeypatch.setattr(mock_block_device.blocks[DEVICE_BLOCK_ID], "valveError", 0)
|
||||
entry = await init_integration(hass, 1, sleep_period=1000, skip_setup=True)
|
||||
register_device(device_registry, entry)
|
||||
device = register_device(device_registry, entry)
|
||||
entity_id = register_entity(
|
||||
hass,
|
||||
CLIMATE_DOMAIN,
|
||||
"test_name",
|
||||
"sensor_0",
|
||||
entry,
|
||||
device_id=device.id,
|
||||
)
|
||||
mock_restore_cache(hass, [State(entity_id, STATE_UNAVAILABLE)])
|
||||
|
||||
|
@ -417,13 +420,14 @@ async def test_block_restored_climate_set_preset_before_online(
|
|||
monkeypatch.delattr(mock_block_device.blocks[DEVICE_BLOCK_ID], "targetTemp")
|
||||
monkeypatch.setattr(mock_block_device.blocks[DEVICE_BLOCK_ID], "valveError", 0)
|
||||
entry = await init_integration(hass, 1, sleep_period=1000, skip_setup=True)
|
||||
register_device(device_registry, entry)
|
||||
device = register_device(device_registry, entry)
|
||||
entity_id = register_entity(
|
||||
hass,
|
||||
CLIMATE_DOMAIN,
|
||||
"test_name",
|
||||
"sensor_0",
|
||||
entry,
|
||||
device_id=device.id,
|
||||
)
|
||||
mock_restore_cache(hass, [State(entity_id, HVACMode.HEAT)])
|
||||
|
||||
|
@ -518,13 +522,14 @@ async def test_block_restored_climate_auth_error(
|
|||
monkeypatch.delattr(mock_block_device.blocks[DEVICE_BLOCK_ID], "targetTemp")
|
||||
monkeypatch.setattr(mock_block_device.blocks[DEVICE_BLOCK_ID], "valveError", 0)
|
||||
entry = await init_integration(hass, 1, sleep_period=1000, skip_setup=True)
|
||||
register_device(device_registry, entry)
|
||||
device = register_device(device_registry, entry)
|
||||
entity_id = register_entity(
|
||||
hass,
|
||||
CLIMATE_DOMAIN,
|
||||
"test_name",
|
||||
"sensor_0",
|
||||
entry,
|
||||
device_id=device.id,
|
||||
)
|
||||
mock_restore_cache(hass, [State(entity_id, HVACMode.HEAT)])
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ from homeassistant.components.shelly.const import (
|
|||
ATTR_DEVICE,
|
||||
ATTR_GENERATION,
|
||||
CONF_BLE_SCANNER_MODE,
|
||||
CONF_SLEEP_PERIOD,
|
||||
DOMAIN,
|
||||
ENTRY_RELOAD_COOLDOWN,
|
||||
MAX_PUSH_UPDATE_FAILURES,
|
||||
|
@ -886,9 +887,14 @@ async def test_block_sleeping_device_connection_error(
|
|||
"""Test block sleeping device connection error during initialize."""
|
||||
sleep_period = 1000
|
||||
entry = await init_integration(hass, 1, sleep_period=sleep_period, skip_setup=True)
|
||||
register_device(device_registry, entry)
|
||||
device = register_device(device_registry, entry)
|
||||
entity_id = register_entity(
|
||||
hass, BINARY_SENSOR_DOMAIN, "test_name_motion", "sensor_0-motion", entry
|
||||
hass,
|
||||
BINARY_SENSOR_DOMAIN,
|
||||
"test_name_motion",
|
||||
"sensor_0-motion",
|
||||
entry,
|
||||
device_id=device.id,
|
||||
)
|
||||
mock_restore_cache(hass, [State(entity_id, STATE_ON)])
|
||||
monkeypatch.setattr(mock_block_device, "initialized", False)
|
||||
|
@ -931,9 +937,14 @@ async def test_rpc_sleeping_device_connection_error(
|
|||
"""Test RPC sleeping device connection error during initialize."""
|
||||
sleep_period = 1000
|
||||
entry = await init_integration(hass, 2, sleep_period=1000, skip_setup=True)
|
||||
register_device(device_registry, entry)
|
||||
device = register_device(device_registry, entry)
|
||||
entity_id = register_entity(
|
||||
hass, BINARY_SENSOR_DOMAIN, "test_name_cloud", "cloud-cloud", entry
|
||||
hass,
|
||||
BINARY_SENSOR_DOMAIN,
|
||||
"test_name_cloud",
|
||||
"cloud-cloud",
|
||||
entry,
|
||||
device_id=device.id,
|
||||
)
|
||||
mock_restore_cache(hass, [State(entity_id, STATE_ON)])
|
||||
monkeypatch.setattr(mock_rpc_device, "connected", False)
|
||||
|
@ -966,6 +977,31 @@ async def test_rpc_sleeping_device_connection_error(
|
|||
assert get_entity_state(hass, entity_id) == STATE_UNAVAILABLE
|
||||
|
||||
|
||||
async def test_rpc_sleeping_device_late_setup(
|
||||
hass: HomeAssistant,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
mock_rpc_device: Mock,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
"""Test RPC sleeping device creates entities if they do not exist yet."""
|
||||
entry = await init_integration(hass, 2, sleep_period=1000, skip_setup=True)
|
||||
monkeypatch.setitem(mock_rpc_device.status["sys"], "wakeup_period", 1000)
|
||||
assert entry.data[CONF_SLEEP_PERIOD] == 1000
|
||||
register_device(device_registry, entry)
|
||||
monkeypatch.setattr(mock_rpc_device, "connected", False)
|
||||
monkeypatch.setattr(mock_rpc_device, "initialized", False)
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
monkeypatch.setattr(mock_rpc_device, "initialized", True)
|
||||
mock_rpc_device.mock_online()
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
monkeypatch.setattr(mock_rpc_device, "connected", True)
|
||||
mock_rpc_device.mock_initialized()
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
assert hass.states.get("sensor.test_name_temperature") is not None
|
||||
|
||||
|
||||
async def test_rpc_already_connected(
|
||||
hass: HomeAssistant,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
|
|
|
@ -72,7 +72,7 @@ async def test_block_restored_number(
|
|||
) -> None:
|
||||
"""Test block restored number."""
|
||||
entry = await init_integration(hass, 1, sleep_period=1000, skip_setup=True)
|
||||
register_device(device_registry, entry)
|
||||
device = register_device(device_registry, entry)
|
||||
capabilities = {
|
||||
"min": 0,
|
||||
"max": 100,
|
||||
|
@ -86,6 +86,7 @@ async def test_block_restored_number(
|
|||
"device_0-valvePos",
|
||||
entry,
|
||||
capabilities,
|
||||
device_id=device.id,
|
||||
)
|
||||
extra_data = {
|
||||
"native_max_value": 100,
|
||||
|
@ -118,7 +119,7 @@ async def test_block_restored_number_no_last_state(
|
|||
) -> None:
|
||||
"""Test block restored number missing last state."""
|
||||
entry = await init_integration(hass, 1, sleep_period=1000, skip_setup=True)
|
||||
register_device(device_registry, entry)
|
||||
device = register_device(device_registry, entry)
|
||||
capabilities = {
|
||||
"min": 0,
|
||||
"max": 100,
|
||||
|
@ -132,6 +133,7 @@ async def test_block_restored_number_no_last_state(
|
|||
"device_0-valvePos",
|
||||
entry,
|
||||
capabilities,
|
||||
device_id=device.id,
|
||||
)
|
||||
monkeypatch.setattr(mock_block_device, "initialized", False)
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
|
|
|
@ -193,9 +193,14 @@ async def test_block_restored_sleeping_sensor(
|
|||
) -> None:
|
||||
"""Test block restored sleeping sensor."""
|
||||
entry = await init_integration(hass, 1, sleep_period=1000, skip_setup=True)
|
||||
register_device(device_registry, entry)
|
||||
device = register_device(device_registry, entry)
|
||||
entity_id = register_entity(
|
||||
hass, SENSOR_DOMAIN, "test_name_temperature", "sensor_0-temp", entry
|
||||
hass,
|
||||
SENSOR_DOMAIN,
|
||||
"test_name_temperature",
|
||||
"sensor_0-temp",
|
||||
entry,
|
||||
device_id=device.id,
|
||||
)
|
||||
extra_data = {"native_value": "20.4", "native_unit_of_measurement": "°C"}
|
||||
|
||||
|
@ -226,9 +231,14 @@ async def test_block_restored_sleeping_sensor_no_last_state(
|
|||
) -> None:
|
||||
"""Test block restored sleeping sensor missing last state."""
|
||||
entry = await init_integration(hass, 1, sleep_period=1000, skip_setup=True)
|
||||
register_device(device_registry, entry)
|
||||
device = register_device(device_registry, entry)
|
||||
entity_id = register_entity(
|
||||
hass, SENSOR_DOMAIN, "test_name_temperature", "sensor_0-temp", entry
|
||||
hass,
|
||||
SENSOR_DOMAIN,
|
||||
"test_name_temperature",
|
||||
"sensor_0-temp",
|
||||
entry,
|
||||
device_id=device.id,
|
||||
)
|
||||
monkeypatch.setattr(mock_block_device, "initialized", False)
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
|
@ -293,9 +303,14 @@ async def test_block_not_matched_restored_sleeping_sensor(
|
|||
) -> None:
|
||||
"""Test block not matched to restored sleeping sensor."""
|
||||
entry = await init_integration(hass, 1, sleep_period=1000, skip_setup=True)
|
||||
register_device(device_registry, entry)
|
||||
device = register_device(device_registry, entry)
|
||||
entity_id = register_entity(
|
||||
hass, SENSOR_DOMAIN, "test_name_temperature", "sensor_0-temp", entry
|
||||
hass,
|
||||
SENSOR_DOMAIN,
|
||||
"test_name_temperature",
|
||||
"sensor_0-temp",
|
||||
entry,
|
||||
device_id=device.id,
|
||||
)
|
||||
extra_data = {"native_value": "20.4", "native_unit_of_measurement": "°C"}
|
||||
|
||||
|
@ -489,13 +504,14 @@ async def test_rpc_restored_sleeping_sensor(
|
|||
) -> None:
|
||||
"""Test RPC restored sensor."""
|
||||
entry = await init_integration(hass, 2, sleep_period=1000, skip_setup=True)
|
||||
register_device(device_registry, entry)
|
||||
device = register_device(device_registry, entry)
|
||||
entity_id = register_entity(
|
||||
hass,
|
||||
SENSOR_DOMAIN,
|
||||
"test_name_temperature",
|
||||
"temperature:0-temperature_0",
|
||||
entry,
|
||||
device_id=device.id,
|
||||
)
|
||||
extra_data = {"native_value": "21.0", "native_unit_of_measurement": "°C"}
|
||||
|
||||
|
@ -527,13 +543,14 @@ async def test_rpc_restored_sleeping_sensor_no_last_state(
|
|||
) -> None:
|
||||
"""Test RPC restored sensor missing last state."""
|
||||
entry = await init_integration(hass, 2, sleep_period=1000, skip_setup=True)
|
||||
register_device(device_registry, entry)
|
||||
device = register_device(device_registry, entry)
|
||||
entity_id = register_entity(
|
||||
hass,
|
||||
SENSOR_DOMAIN,
|
||||
"test_name_temperature",
|
||||
"temperature:0-temperature_0",
|
||||
entry,
|
||||
device_id=device.id,
|
||||
)
|
||||
|
||||
monkeypatch.setattr(mock_rpc_device, "initialized", False)
|
||||
|
|
|
@ -118,13 +118,14 @@ async def test_block_restored_motion_switch(
|
|||
entry = await init_integration(
|
||||
hass, 1, sleep_period=1000, model=model, skip_setup=True
|
||||
)
|
||||
register_device(device_registry, entry)
|
||||
device = register_device(device_registry, entry)
|
||||
entity_id = register_entity(
|
||||
hass,
|
||||
SWITCH_DOMAIN,
|
||||
"test_name_motion_detection",
|
||||
"sensor_0-motionActive",
|
||||
entry,
|
||||
device_id=device.id,
|
||||
)
|
||||
|
||||
mock_restore_cache(hass, [State(entity_id, STATE_OFF)])
|
||||
|
@ -154,13 +155,14 @@ async def test_block_restored_motion_switch_no_last_state(
|
|||
entry = await init_integration(
|
||||
hass, 1, sleep_period=1000, model=model, skip_setup=True
|
||||
)
|
||||
register_device(device_registry, entry)
|
||||
device = register_device(device_registry, entry)
|
||||
entity_id = register_entity(
|
||||
hass,
|
||||
SWITCH_DOMAIN,
|
||||
"test_name_motion_detection",
|
||||
"sensor_0-motionActive",
|
||||
entry,
|
||||
device_id=device.id,
|
||||
)
|
||||
monkeypatch.setattr(mock_block_device, "initialized", False)
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
|
|
|
@ -385,13 +385,14 @@ async def test_rpc_restored_sleeping_update(
|
|||
) -> None:
|
||||
"""Test RPC restored update entity."""
|
||||
entry = await init_integration(hass, 2, sleep_period=1000, skip_setup=True)
|
||||
register_device(device_registry, entry)
|
||||
device = register_device(device_registry, entry)
|
||||
entity_id = register_entity(
|
||||
hass,
|
||||
UPDATE_DOMAIN,
|
||||
"test_name_firmware_update",
|
||||
"sys-fwupdate",
|
||||
entry,
|
||||
device_id=device.id,
|
||||
)
|
||||
|
||||
attr = {ATTR_INSTALLED_VERSION: "1", ATTR_LATEST_VERSION: "2"}
|
||||
|
@ -443,13 +444,14 @@ async def test_rpc_restored_sleeping_update_no_last_state(
|
|||
},
|
||||
)
|
||||
entry = await init_integration(hass, 2, sleep_period=1000, skip_setup=True)
|
||||
register_device(device_registry, entry)
|
||||
device = register_device(device_registry, entry)
|
||||
entity_id = register_entity(
|
||||
hass,
|
||||
UPDATE_DOMAIN,
|
||||
"test_name_firmware_update",
|
||||
"sys-fwupdate",
|
||||
entry,
|
||||
device_id=device.id,
|
||||
)
|
||||
|
||||
monkeypatch.setattr(mock_rpc_device, "initialized", False)
|
||||
|
|
Loading…
Add table
Reference in a new issue