Reolink change ir to switch (#105916)

* Change IR from light to switch

* Remove old entity

* Add test

* Apply suggestions from code review

Co-authored-by: Jan-Philipp Benecke <github@bnck.me>

---------

Co-authored-by: Jan-Philipp Benecke <github@bnck.me>
This commit is contained in:
starkillerOG 2023-12-18 11:13:20 +01:00 committed by GitHub
parent 3e50ca6cda
commit 253182c650
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 58 additions and 15 deletions

View file

@ -16,7 +16,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EVENT_HOMEASSISTANT_STOP, Platform from homeassistant.const import EVENT_HOMEASSISTANT_STOP, Platform
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
from homeassistant.helpers import device_registry as dr from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import DOMAIN from .const import DOMAIN
@ -151,6 +151,13 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
cleanup_disconnected_cams(hass, config_entry.entry_id, host) cleanup_disconnected_cams(hass, config_entry.entry_id, host)
# Can be remove in HA 2024.6.0
entity_reg = er.async_get(hass)
entities = er.async_entries_for_config_entry(entity_reg, config_entry.entry_id)
for entity in entities:
if entity.domain == "light" and entity.unique_id.endswith("ir_lights"):
entity_reg.async_remove(entity.entity_id)
await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS) await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS)
config_entry.async_on_unload( config_entry.async_on_unload(

View file

@ -50,16 +50,6 @@ LIGHT_ENTITIES = (
get_brightness_fn=lambda api, ch: api.whiteled_brightness(ch), get_brightness_fn=lambda api, ch: api.whiteled_brightness(ch),
set_brightness_fn=lambda api, ch, value: api.set_whiteled(ch, brightness=value), set_brightness_fn=lambda api, ch, value: api.set_whiteled(ch, brightness=value),
), ),
ReolinkLightEntityDescription(
key="ir_lights",
cmd_key="GetIrLights",
translation_key="ir_lights",
icon="mdi:led-off",
entity_category=EntityCategory.CONFIG,
supported=lambda api, ch: api.supported(ch, "ir_lights"),
is_on_fn=lambda api, ch: api.ir_enabled(ch),
turn_on_off_fn=lambda api, ch, value: api.set_ir_lights(ch, value),
),
ReolinkLightEntityDescription( ReolinkLightEntityDescription(
key="status_led", key="status_led",
cmd_key="GetPowerLed", cmd_key="GetPowerLed",

View file

@ -238,9 +238,6 @@
"floodlight": { "floodlight": {
"name": "Floodlight" "name": "Floodlight"
}, },
"ir_lights": {
"name": "Infra red lights in night mode"
},
"status_led": { "status_led": {
"name": "Status LED" "name": "Status LED"
} }
@ -373,6 +370,9 @@
} }
}, },
"switch": { "switch": {
"ir_lights": {
"name": "Infra red lights in night mode"
},
"record_audio": { "record_audio": {
"name": "Record audio" "name": "Record audio"
}, },

View file

@ -48,6 +48,16 @@ class ReolinkNVRSwitchEntityDescription(
SWITCH_ENTITIES = ( SWITCH_ENTITIES = (
ReolinkSwitchEntityDescription(
key="ir_lights",
cmd_key="GetIrLights",
translation_key="ir_lights",
icon="mdi:led-off",
entity_category=EntityCategory.CONFIG,
supported=lambda api, ch: api.supported(ch, "ir_lights"),
value=lambda api, ch: api.ir_enabled(ch),
method=lambda api, ch, value: api.set_ir_lights(ch, value),
),
ReolinkSwitchEntityDescription( ReolinkSwitchEntityDescription(
key="record_audio", key="record_audio",
cmd_key="GetEnc", cmd_key="GetEnc",

View file

@ -19,7 +19,7 @@ from homeassistant.helpers import (
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
from homeassistant.util.dt import utcnow from homeassistant.util.dt import utcnow
from .conftest import TEST_CAM_MODEL, TEST_HOST_MODEL, TEST_NVR_NAME from .conftest import TEST_CAM_MODEL, TEST_HOST_MODEL, TEST_MAC, TEST_NVR_NAME
from tests.common import MockConfigEntry, async_fire_time_changed from tests.common import MockConfigEntry, async_fire_time_changed
@ -172,6 +172,42 @@ async def test_cleanup_disconnected_cams(
assert sorted(device_models) == sorted(expected_models) assert sorted(device_models) == sorted(expected_models)
async def test_cleanup_deprecated_entities(
hass: HomeAssistant,
config_entry: MockConfigEntry,
reolink_connect: MagicMock,
entity_registry: er.EntityRegistry,
) -> None:
"""Test deprecated ir_lights light entity is cleaned."""
reolink_connect.channels = [0]
ir_id = f"{TEST_MAC}_0_ir_lights"
entity_registry.async_get_or_create(
domain=Platform.LIGHT,
platform=const.DOMAIN,
unique_id=ir_id,
config_entry=config_entry,
suggested_object_id=ir_id,
disabled_by=None,
)
assert entity_registry.async_get_entity_id(Platform.LIGHT, const.DOMAIN, ir_id)
assert (
entity_registry.async_get_entity_id(Platform.SWITCH, const.DOMAIN, ir_id)
is None
)
# setup CH 0 and NVR switch entities/device
with patch("homeassistant.components.reolink.PLATFORMS", [Platform.SWITCH]):
assert await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
assert (
entity_registry.async_get_entity_id(Platform.LIGHT, const.DOMAIN, ir_id) is None
)
assert entity_registry.async_get_entity_id(Platform.SWITCH, const.DOMAIN, ir_id)
async def test_no_repair_issue( async def test_no_repair_issue(
hass: HomeAssistant, config_entry: MockConfigEntry hass: HomeAssistant, config_entry: MockConfigEntry
) -> None: ) -> None: