Skip to content

Commit

Permalink
Migrate Twinkly to has entity naming (#97206)
Browse files Browse the repository at this point in the history
* Migrate Twinkly to has entity naming

* Update the device name after sync

* Fix tests

---------

Co-authored-by: Franck Nijhof <[email protected]>
  • Loading branch information
joostlek and frenck authored Feb 14, 2024
1 parent 538ef77 commit 0e833c5
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 15 deletions.
20 changes: 13 additions & 7 deletions homeassistant/components/twinkly/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__(
Expand Down Expand Up @@ -92,7 +94,7 @@ def __init__(
# 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
Expand All @@ -106,19 +108,14 @@ def __init__(
# 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."""
return DeviceInfo(
identifiers={(DOMAIN, self._attr_unique_id)},
manufacturer="LEDWORKS",
model=self._model,
name=self.name,
name=self._name,
sw_version=self._software_version,
)

Expand Down Expand Up @@ -271,6 +268,15 @@ async def async_update(self) -> None:
},
)

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()
Expand Down
22 changes: 14 additions & 8 deletions tests/components/twinkly/test_light.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -13,7 +16,7 @@

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:
Expand All @@ -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
Expand Down Expand Up @@ -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,
Expand All @@ -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:
Expand Down

0 comments on commit 0e833c5

Please sign in to comment.