Remove Reolink Home Hub main level switches (#126697)
Co-authored-by: Robert Resch <robert@resch.dev>
This commit is contained in:
parent
90dcb02429
commit
1395baef01
4 changed files with 231 additions and 8 deletions
|
@ -83,6 +83,10 @@
|
|||
"hdr_switch_deprecated": {
|
||||
"title": "Reolink HDR switch deprecated",
|
||||
"description": "The Reolink HDR switch entity is deprecated and will be removed in HA 2025.2.0. It has been replaced by a HDR select entity offering options `on`, `off` and `auto`. To remove this issue, please adjust automations accordingly and disable the HDR switch entity."
|
||||
},
|
||||
"hub_switch_deprecated": {
|
||||
"title": "Reolink Home Hub switches deprecated",
|
||||
"description": "The redundant 'Record', 'Email on event', 'FTP upload', 'Push notifications', and 'Buzzer on event' switches on the Reolink Home Hub are depricated since the new firmware no longer supports these. Please use the equally named switches under each of the camera devices connected to the Home Hub instead. To remove this issue, please adjust automations accordingly and disable the switch entities mentioned."
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
|
|
|
@ -214,7 +214,7 @@ NVR_SWITCH_ENTITIES = (
|
|||
cmd_key="GetEmail",
|
||||
translation_key="email",
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
supported=lambda api: api.supported(None, "email"),
|
||||
supported=lambda api: api.supported(None, "email") and not api.is_hub,
|
||||
value=lambda api: api.email_enabled(),
|
||||
method=lambda api, value: api.set_email(None, value),
|
||||
),
|
||||
|
@ -223,7 +223,7 @@ NVR_SWITCH_ENTITIES = (
|
|||
cmd_key="GetFtp",
|
||||
translation_key="ftp_upload",
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
supported=lambda api: api.supported(None, "ftp"),
|
||||
supported=lambda api: api.supported(None, "ftp") and not api.is_hub,
|
||||
value=lambda api: api.ftp_enabled(),
|
||||
method=lambda api, value: api.set_ftp(None, value),
|
||||
),
|
||||
|
@ -232,7 +232,7 @@ NVR_SWITCH_ENTITIES = (
|
|||
cmd_key="GetPush",
|
||||
translation_key="push_notifications",
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
supported=lambda api: api.supported(None, "push"),
|
||||
supported=lambda api: api.supported(None, "push") and not api.is_hub,
|
||||
value=lambda api: api.push_enabled(),
|
||||
method=lambda api, value: api.set_push(None, value),
|
||||
),
|
||||
|
@ -241,7 +241,7 @@ NVR_SWITCH_ENTITIES = (
|
|||
cmd_key="GetRec",
|
||||
translation_key="record",
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
supported=lambda api: api.supported(None, "recording"),
|
||||
supported=lambda api: api.supported(None, "recording") and not api.is_hub,
|
||||
value=lambda api: api.recording_enabled(),
|
||||
method=lambda api, value: api.set_recording(None, value),
|
||||
),
|
||||
|
@ -250,7 +250,7 @@ NVR_SWITCH_ENTITIES = (
|
|||
cmd_key="GetBuzzerAlarmV20",
|
||||
translation_key="hub_ringtone_on_event",
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
supported=lambda api: api.supported(None, "buzzer"),
|
||||
supported=lambda api: api.supported(None, "buzzer") and not api.is_hub,
|
||||
value=lambda api: api.buzzer_enabled(),
|
||||
method=lambda api, value: api.set_buzzer(None, value),
|
||||
),
|
||||
|
@ -279,6 +279,56 @@ DEPRECATED_HDR = ReolinkSwitchEntityDescription(
|
|||
method=lambda api, ch, value: api.set_HDR(ch, value),
|
||||
)
|
||||
|
||||
# Can be removed in HA 2025.4.0
|
||||
DEPRECATED_NVR_SWITCHES = [
|
||||
ReolinkNVRSwitchEntityDescription(
|
||||
key="email",
|
||||
cmd_key="GetEmail",
|
||||
translation_key="email",
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
supported=lambda api: api.is_hub,
|
||||
value=lambda api: api.email_enabled(),
|
||||
method=lambda api, value: api.set_email(None, value),
|
||||
),
|
||||
ReolinkNVRSwitchEntityDescription(
|
||||
key="ftp_upload",
|
||||
cmd_key="GetFtp",
|
||||
translation_key="ftp_upload",
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
supported=lambda api: api.is_hub,
|
||||
value=lambda api: api.ftp_enabled(),
|
||||
method=lambda api, value: api.set_ftp(None, value),
|
||||
),
|
||||
ReolinkNVRSwitchEntityDescription(
|
||||
key="push_notifications",
|
||||
cmd_key="GetPush",
|
||||
translation_key="push_notifications",
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
supported=lambda api: api.is_hub,
|
||||
value=lambda api: api.push_enabled(),
|
||||
method=lambda api, value: api.set_push(None, value),
|
||||
),
|
||||
ReolinkNVRSwitchEntityDescription(
|
||||
key="record",
|
||||
cmd_key="GetRec",
|
||||
translation_key="record",
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
supported=lambda api: api.is_hub,
|
||||
value=lambda api: api.recording_enabled(),
|
||||
method=lambda api, value: api.set_recording(None, value),
|
||||
),
|
||||
ReolinkNVRSwitchEntityDescription(
|
||||
key="buzzer",
|
||||
cmd_key="GetBuzzerAlarmV20",
|
||||
translation_key="hub_ringtone_on_event",
|
||||
icon="mdi:room-service",
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
supported=lambda api: api.is_hub,
|
||||
value=lambda api: api.buzzer_enabled(),
|
||||
method=lambda api, value: api.set_buzzer(None, value),
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
|
@ -307,10 +357,17 @@ async def async_setup_entry(
|
|||
for chime in reolink_data.host.api.chime_list
|
||||
)
|
||||
|
||||
# Can be removed in HA 2025.2.0
|
||||
# Can be removed in HA 2025.4.0
|
||||
depricated_dict = {}
|
||||
for desc in DEPRECATED_NVR_SWITCHES:
|
||||
if not desc.supported(reolink_data.host.api):
|
||||
continue
|
||||
depricated_dict[f"{reolink_data.host.unique_id}_{desc.key}"] = desc
|
||||
|
||||
entity_reg = er.async_get(hass)
|
||||
reg_entities = er.async_entries_for_config_entry(entity_reg, config_entry.entry_id)
|
||||
for entity in reg_entities:
|
||||
# Can be removed in HA 2025.2.0
|
||||
if entity.domain == "switch" and entity.unique_id.endswith("_hdr"):
|
||||
if entity.disabled:
|
||||
entity_reg.async_remove(entity.entity_id)
|
||||
|
@ -329,7 +386,24 @@ async def async_setup_entry(
|
|||
for channel in reolink_data.host.api.channels
|
||||
if DEPRECATED_HDR.supported(reolink_data.host.api, channel)
|
||||
)
|
||||
break
|
||||
|
||||
# Can be removed in HA 2025.4.0
|
||||
if entity.domain == "switch" and entity.unique_id in depricated_dict:
|
||||
if entity.disabled:
|
||||
entity_reg.async_remove(entity.entity_id)
|
||||
continue
|
||||
|
||||
ir.async_create_issue(
|
||||
hass,
|
||||
DOMAIN,
|
||||
"hub_switch_deprecated",
|
||||
is_fixable=False,
|
||||
severity=ir.IssueSeverity.WARNING,
|
||||
translation_key="hub_switch_deprecated",
|
||||
)
|
||||
entities.append(
|
||||
ReolinkNVRSwitchEntity(reolink_data, depricated_dict[entity.unique_id])
|
||||
)
|
||||
|
||||
async_add_entities(entities)
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@ def reolink_connect_class() -> Generator[MagicMock]:
|
|||
host_mock.check_new_firmware.return_value = False
|
||||
host_mock.unsubscribe.return_value = True
|
||||
host_mock.logout.return_value = True
|
||||
host_mock.is_hub = False
|
||||
host_mock.mac_address = TEST_MAC
|
||||
host_mock.uid = TEST_UID
|
||||
host_mock.onvif_enabled = True
|
||||
|
|
|
@ -28,7 +28,7 @@ from .conftest import TEST_CAM_NAME, TEST_NVR_NAME, TEST_UID
|
|||
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||
|
||||
|
||||
async def test_cleanup_hdr_switch_(
|
||||
async def test_cleanup_hdr_switch(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
reolink_connect: MagicMock,
|
||||
|
@ -60,6 +60,77 @@ async def test_cleanup_hdr_switch_(
|
|||
assert entity_registry.async_get_entity_id(domain, DOMAIN, original_id) is None
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
(
|
||||
"original_id",
|
||||
"capability",
|
||||
),
|
||||
[
|
||||
(
|
||||
f"{TEST_UID}_record",
|
||||
"recording",
|
||||
),
|
||||
(
|
||||
f"{TEST_UID}_ftp_upload",
|
||||
"ftp",
|
||||
),
|
||||
(
|
||||
f"{TEST_UID}_push_notifications",
|
||||
"push",
|
||||
),
|
||||
(
|
||||
f"{TEST_UID}_email",
|
||||
"email",
|
||||
),
|
||||
(
|
||||
f"{TEST_UID}_buzzer",
|
||||
"buzzer",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_cleanup_hub_switches(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
reolink_connect: MagicMock,
|
||||
entity_registry: er.EntityRegistry,
|
||||
original_id: str,
|
||||
capability: str,
|
||||
) -> None:
|
||||
"""Test entity ids that need to be migrated."""
|
||||
|
||||
def mock_supported(ch, cap):
|
||||
if cap == capability:
|
||||
return False
|
||||
return True
|
||||
|
||||
domain = Platform.SWITCH
|
||||
|
||||
reolink_connect.channels = [0]
|
||||
reolink_connect.is_hub = True
|
||||
reolink_connect.supported = mock_supported
|
||||
|
||||
entity_registry.async_get_or_create(
|
||||
domain=domain,
|
||||
platform=DOMAIN,
|
||||
unique_id=original_id,
|
||||
config_entry=config_entry,
|
||||
suggested_object_id=original_id,
|
||||
disabled_by=er.RegistryEntryDisabler.USER,
|
||||
)
|
||||
|
||||
assert entity_registry.async_get_entity_id(domain, DOMAIN, original_id)
|
||||
|
||||
# setup CH 0 and host entities/device
|
||||
with patch("homeassistant.components.reolink.PLATFORMS", [domain]):
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entity_registry.async_get_entity_id(domain, DOMAIN, original_id) is None
|
||||
|
||||
reolink_connect.is_hub = False
|
||||
reolink_connect.supported.return_value = True
|
||||
|
||||
|
||||
async def test_hdr_switch_deprecated_repair_issue(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
|
@ -95,6 +166,79 @@ async def test_hdr_switch_deprecated_repair_issue(
|
|||
assert (DOMAIN, "hdr_switch_deprecated") in issue_registry.issues
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
(
|
||||
"original_id",
|
||||
"capability",
|
||||
),
|
||||
[
|
||||
(
|
||||
f"{TEST_UID}_record",
|
||||
"recording",
|
||||
),
|
||||
(
|
||||
f"{TEST_UID}_ftp_upload",
|
||||
"ftp",
|
||||
),
|
||||
(
|
||||
f"{TEST_UID}_push_notifications",
|
||||
"push",
|
||||
),
|
||||
(
|
||||
f"{TEST_UID}_email",
|
||||
"email",
|
||||
),
|
||||
(
|
||||
f"{TEST_UID}_buzzer",
|
||||
"buzzer",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_hub_switches_repair_issue(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
reolink_connect: MagicMock,
|
||||
entity_registry: er.EntityRegistry,
|
||||
issue_registry: ir.IssueRegistry,
|
||||
original_id: str,
|
||||
capability: str,
|
||||
) -> None:
|
||||
"""Test entity ids that need to be migrated."""
|
||||
|
||||
def mock_supported(ch, cap):
|
||||
if cap == capability:
|
||||
return False
|
||||
return True
|
||||
|
||||
domain = Platform.SWITCH
|
||||
|
||||
reolink_connect.channels = [0]
|
||||
reolink_connect.is_hub = True
|
||||
reolink_connect.supported = mock_supported
|
||||
|
||||
entity_registry.async_get_or_create(
|
||||
domain=domain,
|
||||
platform=DOMAIN,
|
||||
unique_id=original_id,
|
||||
config_entry=config_entry,
|
||||
suggested_object_id=original_id,
|
||||
disabled_by=None,
|
||||
)
|
||||
|
||||
assert entity_registry.async_get_entity_id(domain, DOMAIN, original_id)
|
||||
|
||||
# setup CH 0 and host entities/device
|
||||
with patch("homeassistant.components.reolink.PLATFORMS", [domain]):
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entity_registry.async_get_entity_id(domain, DOMAIN, original_id)
|
||||
assert (DOMAIN, "hub_switch_deprecated") in issue_registry.issues
|
||||
|
||||
reolink_connect.is_hub = False
|
||||
reolink_connect.supported.return_value = True
|
||||
|
||||
|
||||
async def test_switch(
|
||||
hass: HomeAssistant,
|
||||
config_entry: MockConfigEntry,
|
||||
|
|
Loading…
Add table
Reference in a new issue