Hi,
I’m new to the Home Assistant integration development but I’m working on a custom integration. Right now I’m kinda stuck with some things. The device I would like to integrate communicates with a Rest API and should make some lights accessible in HA.
My problem is that I cannot get the integration/device/entities to show up correctly in HA.
-
This is my integration page not showing any devices or entities:
-
Eventhough there are some entities that are created and/or removed by the integration:
-
Additionally the entities do have this property that should create a device connected to the entities as well.
@property
def device_info(self) -> DeviceInfo:
...
Can someone help me? What am I missing to have this devices getting created when using the integration?
You can find my integration code files attached:
__init__.py
“”“The Lunatone integration.”“”
from future import annotations
from dataclasses import dataclass
import logging
from lunatone_dali_api_client import Auth, Devices
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_URL, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
PLATFORMS: list[Platform] = [Platform.LIGHT]
_LOGGER = logging.getLogger(name)
@dataclass
class LunatoneDALIIoTData:
“”“Lunatone DALI IoT data class.”“”
coordinator: DataUpdateCoordinator
devices: Devices
type LunatoneDALIIoTConfigEntry = ConfigEntry[LunatoneDALIIoTData]
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) → bool:
“”“Set up Lunatone from a config entry.”“”
auth = Auth(async_get_clientsession(hass), entry.data[CONF_URL])
devices = Devices(auth)
coordinator = DataUpdateCoordinator(
hass,
_LOGGER,
name="Lunatone",
update_method=devices.async_update,
)
await coordinator.async_config_entry_first_refresh()
entry.runtime_data = LunatoneDALIIoTData(coordinator, devices)
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) → bool:
“”“Unload a config entry.”“”
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
config_flow.py
“”“Config flow for Lunatone.”“”
import logging
from typing import Any
import aiohttp
from lunatone_dali_api_client import APIClient, Auth
import voluptuous as vol
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.const import CONF_URL
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import DOMAIN
_LOGGER = logging.getLogger(name)
class LunatoneDALIIoTConfigFlow(ConfigFlow, domain=DOMAIN):
“”“Lunatone DALI IoT config flow.”“”
VERSION = 0
MINOR_VERSION = 1
def __init__(self) -> None:
"""Initialize the config flow."""
self.data: dict[str, Any] = {}
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle a flow initialized by the user."""
errors: dict[str, str] = {}
if user_input is not None:
self._async_abort_entries_match({CONF_URL: user_input[CONF_URL]})
auth = Auth(
session=async_get_clientsession(self.hass),
base_url=user_input[CONF_URL],
)
client = APIClient(auth)
try:
device_info = await client.async_get_info()
except aiohttp.ClientConnectionError:
_LOGGER.debug(
(
"Failed to connect to device %s. Check the URL and if the "
"device is connected to power"
),
user_input[CONF_URL],
)
errors["base"] = "cannot_connect"
else:
await self.async_set_unique_id(f"lunatone-{device_info.device.serial}")
self._abort_if_unique_id_configured()
return self.async_create_entry(
title=f"DALI IoT Gateway {user_input[CONF_URL].split("//")[1]}",
data={CONF_URL: user_input[CONF_URL]},
)
return self.async_show_form(
step_id="user",
data_schema=vol.Schema({vol.Required(CONF_URL): str}),
errors=errors,
)
light.py
“”“Platform for light integration.”“”
from future import annotations
from typing import Any
from lunatone_dali_api_client import Device
from lunatone_dali_api_client.models import ControlData
from homeassistant.components.light import ColorMode, LightEntity
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import LunatoneDALIIoTConfigEntry
from .const import DOMAIN
async def async_setup_entry(
hass: HomeAssistant,
config_entry: LunatoneDALIIoTConfigEntry,
async_add_entities: AddEntitiesCallback,
) → None:
“”“Set up the Lunatone Light platform.”“”
devices = config_entry.runtime_data.devices
# Add devices
async_add_entities(
[LunatoneLight(device) for device in devices.devices], update_before_add=True
)
class LunatoneLight(LightEntity):
“”“Representation of a Lunatone Light.”“”
_attr_color_mode = ColorMode.ONOFF
_attr_supported_color_modes = {ColorMode.ONOFF}
def __init__(self, device: Device) -> None:
"""Initialize a LunatoneLight."""
self._device = device
self._state = None
@property
def name(self) -> str:
"""Return the display name of this light."""
return self._device.data.name
@property
def is_on(self) -> bool | None:
"""Return true if light is on."""
return self._state
@property
def device_info(self) -> DeviceInfo:
"""Return the device info."""
return DeviceInfo(
identifiers={
(
DOMAIN,
f"lunatone-l{self._device.data.line}-a{self._device.data.address}",
)
},
name=self.name,
manufacturer="Lunatone",
)
async def async_turn_on(self, **kwargs: Any) -> None:
"""Instruct the light to turn on."""
await self._device.async_control(ControlData(switchable=True))
async def async_turn_off(self, **kwargs: Any) -> None:
"""Instruct the light to turn off."""
await self._device.async_control(ControlData(switchable=False))
async def async_update(self) -> None:
"""Fetch new state data for this light.
This is the only method that should fetch new data for Home Assistant.
"""
await self._device.async_update()
features = self._device.data.features
self._state = features.switchable.status