Cleanups in Twinkly code (#64139)

* Cleanup Twinkly code

* Add codeowner'

* Change const names
pull/64159/head
Rob Bierbooms 2022-01-14 22:07:15 +01:00 committed by GitHub
parent e609f196bc
commit efe34c8d13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 124 additions and 194 deletions

View File

@ -973,8 +973,8 @@ homeassistant/components/tuya/* @Tuya @zlinoliver @METISU @frenck
tests/components/tuya/* @Tuya @zlinoliver @METISU @frenck
homeassistant/components/twentemilieu/* @frenck
tests/components/twentemilieu/* @frenck
homeassistant/components/twinkly/* @dr1rrb
tests/components/twinkly/* @dr1rrb
homeassistant/components/twinkly/* @dr1rrb @Robbie1221
tests/components/twinkly/* @dr1rrb @Robbie1221
homeassistant/components/ubus/* @noltari
homeassistant/components/unifi/* @Kane610
tests/components/unifi/* @Kane610

View File

@ -11,7 +11,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import CONF_ENTRY_HOST, CONF_ENTRY_ID, DATA_CLIENT, DATA_DEVICE_INFO, DOMAIN
from .const import CONF_HOST, DATA_CLIENT, DATA_DEVICE_INFO, DOMAIN
PLATFORMS = [Platform.LIGHT]
@ -22,10 +22,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
# We setup the client here so if at some point we add any other entity for this device,
# we will be able to properly share the connection.
uuid = entry.data[CONF_ENTRY_ID]
host = entry.data[CONF_ENTRY_HOST]
host = entry.data[CONF_HOST]
hass.data[DOMAIN].setdefault(uuid, {})
hass.data[DOMAIN].setdefault(entry.entry_id, {})
client = Twinkly(host, async_get_clientsession(hass))
@ -34,8 +33,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
except (asyncio.TimeoutError, ClientError) as exception:
raise ConfigEntryNotReady from exception
hass.data[DOMAIN][uuid][DATA_CLIENT] = client
hass.data[DOMAIN][uuid][DATA_DEVICE_INFO] = device_info
hass.data[DOMAIN][entry.entry_id][DATA_CLIENT] = client
hass.data[DOMAIN][entry.entry_id][DATA_DEVICE_INFO] = device_info
hass.config_entries.async_setup_platforms(entry, PLATFORMS)
@ -45,9 +44,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Remove a twinkly entry."""
# For now light entries don't have unload method, so we don't have to async_forward_entry_unload
# However we still have to cleanup the shared client!
uuid = entry.data[CONF_ENTRY_ID]
hass.data[DOMAIN].pop(uuid)
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
if unload_ok:
hass.data[DOMAIN].pop(entry.entry_id)
return True
return unload_ok

View File

@ -14,16 +14,7 @@ from homeassistant.components import dhcp
from homeassistant.const import CONF_HOST
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import (
CONF_ENTRY_HOST,
CONF_ENTRY_ID,
CONF_ENTRY_MODEL,
CONF_ENTRY_NAME,
DEV_ID,
DEV_MODEL,
DEV_NAME,
DOMAIN,
)
from .const import CONF_ID, CONF_MODEL, CONF_NAME, DEV_ID, DEV_MODEL, DEV_NAME, DOMAIN
_LOGGER = logging.getLogger(__name__)
@ -49,16 +40,14 @@ class TwinklyConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
device_info = await Twinkly(
host, async_get_clientsession(self.hass)
).get_details()
except (asyncio.TimeoutError, ClientError):
errors[CONF_HOST] = "cannot_connect"
else:
await self.async_set_unique_id(device_info[DEV_ID])
self._abort_if_unique_id_configured()
return self._create_entry_from_device(device_info, host)
except (asyncio.TimeoutError, ClientError) as err:
_LOGGER.info("Cannot reach Twinkly '%s' (client)", host, exc_info=err)
errors[CONF_HOST] = "cannot_connect"
return self.async_show_form(
step_id="user", data_schema=Schema(schema), errors=errors
)
@ -67,14 +56,12 @@ class TwinklyConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
self, discovery_info: dhcp.DhcpServiceInfo
) -> data_entry_flow.FlowResult:
"""Handle dhcp discovery for twinkly."""
self._async_abort_entries_match({CONF_ENTRY_HOST: discovery_info.ip})
self._async_abort_entries_match({CONF_HOST: discovery_info.ip})
device_info = await Twinkly(
discovery_info.ip, async_get_clientsession(self.hass)
).get_details()
await self.async_set_unique_id(device_info[DEV_ID])
self._abort_if_unique_id_configured(
updates={CONF_ENTRY_HOST: discovery_info.ip}
)
self._abort_if_unique_id_configured(updates={CONF_HOST: discovery_info.ip})
self._discovered_device = (device_info, discovery_info.ip)
return await self.async_step_discovery_confirm()
@ -106,9 +93,9 @@ class TwinklyConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
return self.async_create_entry(
title=device_info[DEV_NAME],
data={
CONF_ENTRY_HOST: host,
CONF_ENTRY_ID: device_info[DEV_ID],
CONF_ENTRY_NAME: device_info[DEV_NAME],
CONF_ENTRY_MODEL: device_info[DEV_MODEL],
CONF_HOST: host,
CONF_ID: device_info[DEV_ID],
CONF_NAME: device_info[DEV_NAME],
CONF_MODEL: device_info[DEV_MODEL],
},
)

View File

@ -3,10 +3,10 @@
DOMAIN = "twinkly"
# Keys of the config entry
CONF_ENTRY_ID = "id"
CONF_ENTRY_HOST = "host"
CONF_ENTRY_NAME = "name"
CONF_ENTRY_MODEL = "model"
CONF_ID = "id"
CONF_HOST = "host"
CONF_NAME = "name"
CONF_MODEL = "model"
# Strongly named HA attributes keys
ATTR_HOST = "host"

View File

@ -3,6 +3,7 @@ from __future__ import annotations
import asyncio
import logging
from typing import Any
from aiohttp import ClientError
from ttls.client import Twinkly
@ -22,11 +23,10 @@ from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import (
ATTR_HOST,
CONF_ENTRY_HOST,
CONF_ENTRY_ID,
CONF_ENTRY_MODEL,
CONF_ENTRY_NAME,
CONF_HOST,
CONF_ID,
CONF_MODEL,
CONF_NAME,
DATA_CLIENT,
DATA_DEVICE_INFO,
DEV_LED_PROFILE,
@ -48,8 +48,8 @@ async def async_setup_entry(
) -> None:
"""Setups an entity from a config entry (UI config flow)."""
client = hass.data[DOMAIN][config_entry.data[CONF_ENTRY_ID]][DATA_CLIENT]
device_info = hass.data[DOMAIN][config_entry.data[CONF_ENTRY_ID]][DATA_DEVICE_INFO]
client = hass.data[DOMAIN][config_entry.entry_id][DATA_CLIENT]
device_info = hass.data[DOMAIN][config_entry.entry_id][DATA_DEVICE_INFO]
entity = TwinklyLight(config_entry, client, device_info)
@ -66,7 +66,7 @@ class TwinklyLight(LightEntity):
device_info,
) -> None:
"""Initialize a TwinklyLight entity."""
self._id = conf.data[CONF_ENTRY_ID]
self._id = conf.data[CONF_ID]
self._conf = conf
if device_info.get(DEV_LED_PROFILE) == DEV_PROFILE_RGBW:
@ -84,20 +84,15 @@ 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_ENTRY_NAME]
self.__model = conf.data[CONF_ENTRY_MODEL]
self._name = conf.data[CONF_NAME]
self._model = conf.data[CONF_MODEL]
self._client = client
# Set default state before any update
self._is_on = False
self._is_available = False
self._attributes = {ATTR_HOST: self._client.host}
@property
def should_poll(self) -> bool:
"""Get a boolean which indicates if this entity should be polled."""
return True
self._attributes: dict[Any, Any] = {}
@property
def available(self) -> bool:
@ -112,12 +107,12 @@ class TwinklyLight(LightEntity):
@property
def name(self) -> str:
"""Name of the device."""
return self.__name if self.__name else "Twinkly light"
return self._name if self._name else "Twinkly light"
@property
def model(self) -> str:
"""Name of the device."""
return self.__model
return self._model
@property
def icon(self) -> str:
@ -127,15 +122,11 @@ class TwinklyLight(LightEntity):
@property
def device_info(self) -> DeviceInfo | None:
"""Get device specific attributes."""
return (
DeviceInfo(
identifiers={(DOMAIN, self._id)},
manufacturer="LEDWORKS",
model=self.model,
name=self.name,
)
if self._id
else None # device_info is available only for entities configured from the UI
return DeviceInfo(
identifiers={(DOMAIN, self._id)},
manufacturer="LEDWORKS",
model=self.model,
name=self.name,
)
@property
@ -149,10 +140,6 @@ class TwinklyLight(LightEntity):
attributes = self._attributes
# Make sure to update any normalized property
attributes[ATTR_HOST] = self._client.host
attributes[ATTR_BRIGHTNESS] = self._attr_brightness
return attributes
async def async_turn_on(self, **kwargs) -> None:
@ -204,7 +191,7 @@ class TwinklyLight(LightEntity):
async def async_update(self) -> None:
"""Asynchronously updates the device properties."""
_LOGGER.info("Updating '%s'", self._client.host)
_LOGGER.debug("Updating '%s'", self._client.host)
try:
self._is_on = await self._client.is_on()
@ -224,25 +211,24 @@ class TwinklyLight(LightEntity):
DEV_NAME in device_info
and DEV_MODEL in device_info
and (
device_info[DEV_NAME] != self.__name
or device_info[DEV_MODEL] != self.__model
device_info[DEV_NAME] != self._name
or device_info[DEV_MODEL] != self._model
)
):
self.__name = device_info[DEV_NAME]
self.__model = device_info[DEV_MODEL]
self._name = device_info[DEV_NAME]
self._model = device_info[DEV_MODEL]
if self._conf is not None:
# If the name has changed, persist it in conf entry,
# so we will be able to restore this new name if hass is started while the LED string is offline.
self.hass.config_entries.async_update_entry(
self._conf,
data={
CONF_ENTRY_HOST: self._client.host, # this cannot change
CONF_ENTRY_ID: self._id, # this cannot change
CONF_ENTRY_NAME: self.__name,
CONF_ENTRY_MODEL: self.__model,
},
)
# If the name has changed, persist it in conf entry,
# so we will be able to restore this new name if hass is started while the LED string is offline.
self.hass.config_entries.async_update_entry(
self._conf,
data={
CONF_HOST: self._client.host, # this cannot change
CONF_ID: self._id, # this cannot change
CONF_NAME: self._name,
CONF_MODEL: self._model,
},
)
for key, value in device_info.items():
if key not in HIDDEN_DEV_VALUES:

View File

@ -3,8 +3,7 @@
"name": "Twinkly",
"documentation": "https://www.home-assistant.io/integrations/twinkly",
"requirements": ["ttls==1.4.2"],
"dependencies": [],
"codeowners": ["@dr1rrb"],
"codeowners": ["@dr1rrb", "@Robbie1221"],
"config_flow": true,
"dhcp": [{ "hostname": "twinkly_*" }],
"iot_class": "local_polling"

View File

@ -5,7 +5,7 @@
"title": "Twinkly",
"description": "Set up your Twinkly led string",
"data": {
"host": "Host (or IP address) of your twinkly device"
"host": "[%key:common::config_flow::data::host%]"
}
},
"discovery_confirm": {

View File

@ -4,10 +4,10 @@ from unittest.mock import patch
from homeassistant import config_entries
from homeassistant.components import dhcp
from homeassistant.components.twinkly.const import (
CONF_ENTRY_HOST,
CONF_ENTRY_ID,
CONF_ENTRY_MODEL,
CONF_ENTRY_NAME,
CONF_HOST,
CONF_ID,
CONF_MODEL,
CONF_NAME,
DOMAIN as TWINKLY_DOMAIN,
)
@ -31,12 +31,12 @@ async def test_invalid_host(hass):
assert result["errors"] == {}
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_ENTRY_HOST: "dummy"},
{CONF_HOST: "dummy"},
)
assert result["type"] == "form"
assert result["step_id"] == "user"
assert result["errors"] == {CONF_ENTRY_HOST: "cannot_connect"}
assert result["errors"] == {CONF_HOST: "cannot_connect"}
async def test_success_flow(hass):
@ -55,16 +55,16 @@ async def test_success_flow(hass):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_ENTRY_HOST: "dummy"},
{CONF_HOST: "dummy"},
)
assert result["type"] == "create_entry"
assert result["title"] == client.id
assert result["data"] == {
CONF_ENTRY_HOST: "dummy",
CONF_ENTRY_ID: client.id,
CONF_ENTRY_NAME: client.id,
CONF_ENTRY_MODEL: TEST_MODEL,
CONF_HOST: "dummy",
CONF_ID: client.id,
CONF_NAME: client.id,
CONF_MODEL: TEST_MODEL,
}
@ -114,10 +114,10 @@ async def test_dhcp_success(hass):
assert result["type"] == "create_entry"
assert result["title"] == client.id
assert result["data"] == {
CONF_ENTRY_HOST: "1.2.3.4",
CONF_ENTRY_ID: client.id,
CONF_ENTRY_NAME: client.id,
CONF_ENTRY_MODEL: TEST_MODEL,
CONF_HOST: "1.2.3.4",
CONF_ID: client.id,
CONF_NAME: client.id,
CONF_MODEL: TEST_MODEL,
}
@ -128,10 +128,10 @@ async def test_dhcp_already_exists(hass):
entry = MockConfigEntry(
domain=TWINKLY_DOMAIN,
data={
CONF_ENTRY_HOST: "1.2.3.4",
CONF_ENTRY_ID: client.id,
CONF_ENTRY_NAME: client.id,
CONF_ENTRY_MODEL: TEST_MODEL,
CONF_HOST: "1.2.3.4",
CONF_ID: client.id,
CONF_NAME: client.id,
CONF_MODEL: TEST_MODEL,
},
unique_id=client.id,
)

View File

@ -3,12 +3,11 @@
from unittest.mock import patch
from uuid import uuid4
from homeassistant.components.twinkly import async_setup_entry, async_unload_entry
from homeassistant.components.twinkly.const import (
CONF_ENTRY_HOST,
CONF_ENTRY_ID,
CONF_ENTRY_MODEL,
CONF_ENTRY_NAME,
CONF_HOST,
CONF_ID,
CONF_MODEL,
CONF_NAME,
DOMAIN as TWINKLY_DOMAIN,
)
from homeassistant.config_entries import ConfigEntryState
@ -23,7 +22,7 @@ from tests.components.twinkly import (
)
async def test_setup_entry(hass: HomeAssistant):
async def test_load_unload_entry(hass: HomeAssistant):
"""Validate that setup entry also configure the client."""
client = ClientMock()
@ -31,47 +30,24 @@ async def test_setup_entry(hass: HomeAssistant):
config_entry = MockConfigEntry(
domain=TWINKLY_DOMAIN,
data={
CONF_ENTRY_HOST: TEST_HOST,
CONF_ENTRY_ID: id,
CONF_ENTRY_NAME: TEST_NAME_ORIGINAL,
CONF_ENTRY_MODEL: TEST_MODEL,
CONF_HOST: TEST_HOST,
CONF_ID: id,
CONF_NAME: TEST_NAME_ORIGINAL,
CONF_MODEL: TEST_MODEL,
},
entry_id=id,
)
def setup_mock(_, __):
return True
config_entry.add_to_hass(hass)
with patch(
"homeassistant.config_entries.ConfigEntries.async_forward_entry_setup",
side_effect=setup_mock,
), patch("homeassistant.components.twinkly.Twinkly", return_value=client):
await async_setup_entry(hass, config_entry)
with patch("homeassistant.components.twinkly.Twinkly", return_value=client):
await hass.config_entries.async_setup(config_entry.entry_id)
assert hass.data[TWINKLY_DOMAIN][id] is not None
assert config_entry.state == ConfigEntryState.LOADED
await hass.config_entries.async_unload(config_entry.entry_id)
async def test_unload_entry(hass: HomeAssistant):
"""Validate that unload entry also clear the client."""
id = str(uuid4())
config_entry = MockConfigEntry(
domain=TWINKLY_DOMAIN,
data={
CONF_ENTRY_HOST: TEST_HOST,
CONF_ENTRY_ID: id,
CONF_ENTRY_NAME: TEST_NAME_ORIGINAL,
CONF_ENTRY_MODEL: TEST_MODEL,
},
entry_id=id,
)
# Put random content at the location where the client should have been placed by setup
hass.data.setdefault(TWINKLY_DOMAIN, {})[id] = config_entry
await async_unload_entry(hass, config_entry)
assert hass.data[TWINKLY_DOMAIN].get(id) is None
assert config_entry.state == ConfigEntryState.NOT_LOADED
async def test_config_entry_not_ready(hass: HomeAssistant):
@ -82,10 +58,10 @@ async def test_config_entry_not_ready(hass: HomeAssistant):
config_entry = MockConfigEntry(
domain=TWINKLY_DOMAIN,
data={
CONF_ENTRY_HOST: TEST_HOST,
CONF_ENTRY_ID: id,
CONF_ENTRY_NAME: TEST_NAME_ORIGINAL,
CONF_ENTRY_MODEL: TEST_MODEL,
CONF_HOST: TEST_HOST,
CONF_ID: id,
CONF_NAME: TEST_NAME_ORIGINAL,
CONF_MODEL: TEST_MODEL,
},
)

View File

@ -3,11 +3,12 @@ from __future__ import annotations
from unittest.mock import patch
from homeassistant.components.light import ATTR_BRIGHTNESS
from homeassistant.components.twinkly.const import (
CONF_ENTRY_HOST,
CONF_ENTRY_ID,
CONF_ENTRY_MODEL,
CONF_ENTRY_NAME,
CONF_HOST,
CONF_ID,
CONF_MODEL,
CONF_NAME,
DOMAIN as TWINKLY_DOMAIN,
)
from homeassistant.core import HomeAssistant
@ -16,25 +17,19 @@ from homeassistant.helpers.device_registry import DeviceEntry
from homeassistant.helpers.entity_registry import RegistryEntry
from tests.common import MockConfigEntry
from tests.components.twinkly import (
TEST_HOST,
TEST_MODEL,
TEST_NAME_ORIGINAL,
ClientMock,
)
from tests.components.twinkly import TEST_MODEL, TEST_NAME_ORIGINAL, ClientMock
async def test_initial_state(hass: HomeAssistant):
"""Validate that entity and device states are updated on startup."""
entity, device, _ = await _create_entries(hass)
entity, device, _, _ = await _create_entries(hass)
state = hass.states.get(entity.entity_id)
# Basic state properties
assert state.name == entity.unique_id
assert state.state == "on"
assert state.attributes["host"] == TEST_HOST
assert state.attributes["brightness"] == 26
assert state.attributes[ATTR_BRIGHTNESS] == 26
assert state.attributes["friendly_name"] == entity.unique_id
assert state.attributes["icon"] == "mdi:string-lights"
@ -54,7 +49,7 @@ async def test_turn_on_off(hass: HomeAssistant):
client = ClientMock()
client.state = False
client.brightness = {"mode": "enabled", "value": 20}
entity, _, _ = await _create_entries(hass, client)
entity, _, _, _ = await _create_entries(hass, client)
assert hass.states.get(entity.entity_id).state == "off"
@ -66,7 +61,7 @@ async def test_turn_on_off(hass: HomeAssistant):
state = hass.states.get(entity.entity_id)
assert state.state == "on"
assert state.attributes["brightness"] == 51
assert state.attributes[ATTR_BRIGHTNESS] == 51
async def test_turn_on_with_brightness(hass: HomeAssistant):
@ -74,7 +69,7 @@ async def test_turn_on_with_brightness(hass: HomeAssistant):
client = ClientMock()
client.state = False
client.brightness = {"mode": "enabled", "value": 20}
entity, _, _ = await _create_entries(hass, client)
entity, _, _, _ = await _create_entries(hass, client)
assert hass.states.get(entity.entity_id).state == "off"
@ -88,7 +83,7 @@ async def test_turn_on_with_brightness(hass: HomeAssistant):
state = hass.states.get(entity.entity_id)
assert state.state == "on"
assert state.attributes["brightness"] == 255
assert state.attributes[ATTR_BRIGHTNESS] == 255
await hass.services.async_call(
"light",
@ -100,7 +95,6 @@ async def test_turn_on_with_brightness(hass: HomeAssistant):
state = hass.states.get(entity.entity_id)
assert state.state == "off"
assert state.attributes["brightness"] == 0
async def test_turn_on_with_color_rgbw(hass: HomeAssistant):
@ -109,7 +103,7 @@ async def test_turn_on_with_color_rgbw(hass: HomeAssistant):
client.state = False
client.device_info["led_profile"] = "RGBW"
client.brightness = {"mode": "enabled", "value": 255}
entity, _, _ = await _create_entries(hass, client)
entity, _, _, _ = await _create_entries(hass, client)
assert hass.states.get(entity.entity_id).state == "off"
@ -132,7 +126,7 @@ async def test_turn_on_with_color_rgb(hass: HomeAssistant):
client.state = False
client.device_info["led_profile"] = "RGB"
client.brightness = {"mode": "enabled", "value": 255}
entity, _, _ = await _create_entries(hass, client)
entity, _, _, _ = await _create_entries(hass, client)
assert hass.states.get(entity.entity_id).state == "off"
@ -151,7 +145,7 @@ async def test_turn_on_with_color_rgb(hass: HomeAssistant):
async def test_turn_off(hass: HomeAssistant):
"""Test support of the light.turn_off service."""
entity, _, _ = await _create_entries(hass)
entity, _, _, _ = await _create_entries(hass)
assert hass.states.get(entity.entity_id).state == "on"
@ -163,7 +157,6 @@ async def test_turn_off(hass: HomeAssistant):
state = hass.states.get(entity.entity_id)
assert state.state == "off"
assert state.attributes["brightness"] == 0
async def test_update_name(hass: HomeAssistant):
@ -174,15 +167,7 @@ async def test_update_name(hass: HomeAssistant):
then the name of the entity is updated and it's also persisted,
so it can be restored when starting HA while Twinkly is offline.
"""
entity, _, client = await _create_entries(hass)
updated_config_entry = None
async def on_update(ha, co):
nonlocal updated_config_entry
updated_config_entry = co
hass.config_entries.async_get_entry(entity.unique_id).add_update_listener(on_update)
entity, _, client, config_entry = await _create_entries(hass)
client.change_name("new_device_name")
await hass.services.async_call(
@ -192,15 +177,14 @@ async def test_update_name(hass: HomeAssistant):
state = hass.states.get(entity.entity_id)
assert updated_config_entry is not None
assert updated_config_entry.data[CONF_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):
"""Validate that entities can be unloaded from the UI."""
_, _, client = await _create_entries(hass)
_, _, client, _ = await _create_entries(hass)
entry_id = client.id
assert await hass.config_entries.async_unload(entry_id)
@ -215,10 +199,10 @@ async def _create_entries(
config_entry = MockConfigEntry(
domain=TWINKLY_DOMAIN,
data={
CONF_ENTRY_HOST: client,
CONF_ENTRY_ID: client.id,
CONF_ENTRY_NAME: TEST_NAME_ORIGINAL,
CONF_ENTRY_MODEL: TEST_MODEL,
CONF_HOST: client,
CONF_ID: client.id,
CONF_NAME: TEST_NAME_ORIGINAL,
CONF_MODEL: TEST_MODEL,
},
entry_id=client.id,
)
@ -230,10 +214,10 @@ async def _create_entries(
entity_registry = er.async_get(hass)
entity_id = entity_registry.async_get_entity_id("light", TWINKLY_DOMAIN, client.id)
entity = entity_registry.async_get(entity_id)
entity_entry = entity_registry.async_get(entity_id)
device = device_registry.async_get_device({(TWINKLY_DOMAIN, client.id)})
assert entity is not None
assert entity_entry is not None
assert device is not None
return entity, device, client
return entity_entry, device, client, config_entry