Migrate Twinkly to has entity naming (#97206)

* Migrate Twinkly to has entity naming

* Update the device name after sync

* Fix tests

---------

Co-authored-by: Franck Nijhof <git@frenck.dev>
pull/110557/head
Joost Lekkerkerker 2024-02-14 16:43:29 +01:00 committed by GitHub
parent 538ef7764e
commit 0e833c5fe3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 15 deletions

View File

@ -64,6 +64,8 @@ async def async_setup_entry(
class TwinklyLight(LightEntity):
"""Implementation of the light for the Twinkly service."""
_attr_has_entity_name = True
_attr_name = None
_attr_icon = "mdi:string-lights"
def __init__(
@ -92,7 +94,7 @@ class TwinklyLight(LightEntity):
# Those are saved in the config entry in order to have meaningful values even
# if the device is currently offline.
# They are expected to be updated using the device_info.
self._name = conf.data[CONF_NAME]
self._name = conf.data[CONF_NAME] or "Twinkly light"
self._model = conf.data[CONF_MODEL]
self._client = client
@ -106,11 +108,6 @@ class TwinklyLight(LightEntity):
# We guess that most devices are "new" and support effects
self._attr_supported_features = LightEntityFeature.EFFECT
@property
def name(self) -> str:
"""Name of the device."""
return self._name if self._name else "Twinkly light"
@property
def device_info(self) -> DeviceInfo | None:
"""Get device specific attributes."""
@ -118,7 +115,7 @@ class TwinklyLight(LightEntity):
identifiers={(DOMAIN, self._attr_unique_id)},
manufacturer="LEDWORKS",
model=self._model,
name=self.name,
name=self._name,
sw_version=self._software_version,
)
@ -271,6 +268,15 @@ class TwinklyLight(LightEntity):
},
)
device_registry = dr.async_get(self.hass)
device_entry = device_registry.async_get_device(
{(DOMAIN, self._attr_unique_id)}
)
if device_entry:
device_registry.async_update_device(
device_entry.id, name=self._name, model=self._model
)
if LightEntityFeature.EFFECT & self.supported_features:
await self.async_update_movies()
await self.async_update_current_movie()

View File

@ -1,8 +1,11 @@
"""Tests for the integration of a twinly device."""
from __future__ import annotations
from datetime import timedelta
from unittest.mock import patch
from freezegun.api import FrozenDateTimeFactory
from homeassistant.components.light import ATTR_BRIGHTNESS, LightEntityFeature
from homeassistant.components.twinkly.const import DOMAIN as TWINKLY_DOMAIN
from homeassistant.const import CONF_HOST, CONF_ID, CONF_MODEL, CONF_NAME
@ -13,7 +16,7 @@ from homeassistant.helpers.entity_registry import RegistryEntry
from . import TEST_MODEL, TEST_NAME, TEST_NAME_ORIGINAL, ClientMock
from tests.common import MockConfigEntry
from tests.common import MockConfigEntry, async_fire_time_changed
async def test_initial_state(hass: HomeAssistant) -> None:
@ -29,7 +32,6 @@ async def test_initial_state(hass: HomeAssistant) -> None:
assert state.attributes["friendly_name"] == TEST_NAME
assert state.attributes["icon"] == "mdi:string-lights"
assert entity.original_name == TEST_NAME
assert entity.original_icon == "mdi:string-lights"
assert device.name == TEST_NAME
@ -283,7 +285,11 @@ async def test_turn_off(hass: HomeAssistant) -> None:
assert state.state == "off"
async def test_update_name(hass: HomeAssistant) -> None:
async def test_update_name(
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
freezer: FrozenDateTimeFactory,
) -> None:
"""Validate device's name update behavior.
Validate that if device name is changed from the Twinkly app,
@ -293,14 +299,14 @@ async def test_update_name(hass: HomeAssistant) -> None:
entity, _, client, config_entry = await _create_entries(hass)
client.change_name("new_device_name")
await hass.services.async_call(
"light", "turn_off", service_data={"entity_id": entity.entity_id}, blocking=True
) # We call turn_off which will automatically cause an async_update
freezer.tick(timedelta(seconds=30))
async_fire_time_changed(hass)
await hass.async_block_till_done()
state = hass.states.get(entity.entity_id)
dev_entry = device_registry.async_get_device({(TWINKLY_DOMAIN, client.id)})
assert dev_entry.name == "new_device_name"
assert config_entry.data[CONF_NAME] == "new_device_name"
assert state.attributes["friendly_name"] == "new_device_name"
async def test_unload(hass: HomeAssistant) -> None: