Register MAC connection for Elgato devices (#64201)
* Register MAC connection for Elgato devices * Add tests, fix namepull/64213/head
parent
32d4f104ff
commit
423674c0c9
|
@ -7,6 +7,7 @@ from elgato import Elgato, ElgatoError, Info
|
|||
|
||||
from homeassistant.components.button import ButtonEntity, ButtonEntityDescription
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_MAC
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity import EntityCategory
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
@ -25,15 +26,17 @@ async def async_setup_entry(
|
|||
) -> None:
|
||||
"""Set up Elgato button based on a config entry."""
|
||||
data: HomeAssistantElgatoData = hass.data[DOMAIN][entry.entry_id]
|
||||
async_add_entities([ElgatoIdentifyButton(data.client, data.info)])
|
||||
async_add_entities(
|
||||
[ElgatoIdentifyButton(data.client, data.info, entry.data.get(CONF_MAC))]
|
||||
)
|
||||
|
||||
|
||||
class ElgatoIdentifyButton(ElgatoEntity, ButtonEntity):
|
||||
"""Defines an Elgato identify button."""
|
||||
|
||||
def __init__(self, client: Elgato, info: Info) -> None:
|
||||
def __init__(self, client: Elgato, info: Info, mac: str | None) -> None:
|
||||
"""Initialize the button entity."""
|
||||
super().__init__(client, info)
|
||||
super().__init__(client, info, mac)
|
||||
self.entity_description = ButtonEntityDescription(
|
||||
key="identify",
|
||||
name="Identify",
|
||||
|
|
|
@ -8,7 +8,7 @@ import voluptuous as vol
|
|||
|
||||
from homeassistant.components import zeroconf
|
||||
from homeassistant.config_entries import ConfigFlow
|
||||
from homeassistant.const import CONF_HOST, CONF_PORT
|
||||
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_PORT
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.data_entry_flow import FlowResult
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
|
@ -24,6 +24,7 @@ class ElgatoFlowHandler(ConfigFlow, domain=DOMAIN):
|
|||
host: str
|
||||
port: int
|
||||
serial_number: str
|
||||
mac: str | None = None
|
||||
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
|
@ -47,6 +48,7 @@ class ElgatoFlowHandler(ConfigFlow, domain=DOMAIN):
|
|||
) -> FlowResult:
|
||||
"""Handle zeroconf discovery."""
|
||||
self.host = discovery_info.host
|
||||
self.mac = discovery_info.properties.get("id")
|
||||
self.port = discovery_info.port or 9123
|
||||
|
||||
try:
|
||||
|
@ -89,6 +91,7 @@ class ElgatoFlowHandler(ConfigFlow, domain=DOMAIN):
|
|||
data={
|
||||
CONF_HOST: self.host,
|
||||
CONF_PORT: self.port,
|
||||
CONF_MAC: self.mac,
|
||||
},
|
||||
)
|
||||
|
||||
|
@ -107,7 +110,7 @@ class ElgatoFlowHandler(ConfigFlow, domain=DOMAIN):
|
|||
info.serial_number, raise_on_progress=raise_on_progress
|
||||
)
|
||||
self._abort_if_unique_id_configured(
|
||||
updates={CONF_HOST: self.host, CONF_PORT: self.port}
|
||||
updates={CONF_HOST: self.host, CONF_PORT: self.port, CONF_MAC: self.mac}
|
||||
)
|
||||
|
||||
self.serial_number = info.serial_number
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
"""Base entity for the Elgato integration."""
|
||||
from __future__ import annotations
|
||||
|
||||
from elgato import Elgato, Info
|
||||
|
||||
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, format_mac
|
||||
from homeassistant.helpers.entity import DeviceInfo, Entity
|
||||
|
||||
from .const import DOMAIN
|
||||
|
@ -10,13 +12,17 @@ from .const import DOMAIN
|
|||
class ElgatoEntity(Entity):
|
||||
"""Defines an Elgato entity."""
|
||||
|
||||
def __init__(self, client: Elgato, info: Info) -> None:
|
||||
def __init__(self, client: Elgato, info: Info, mac: str | None) -> None:
|
||||
"""Initialize an Elgato entity."""
|
||||
self.client = client
|
||||
self._attr_device_info = DeviceInfo(
|
||||
identifiers={(DOMAIN, info.serial_number)},
|
||||
manufacturer="Elgato",
|
||||
model=info.product_name,
|
||||
name=info.product_name,
|
||||
name=info.display_name,
|
||||
sw_version=f"{info.firmware_version} ({info.firmware_build_number})",
|
||||
)
|
||||
if mac is not None:
|
||||
self._attr_device_info["connections"] = {
|
||||
(CONNECTION_NETWORK_MAC, format_mac(mac))
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ from homeassistant.components.light import (
|
|||
LightEntity,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_MAC
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import (
|
||||
AddEntitiesCallback,
|
||||
|
@ -40,7 +41,9 @@ async def async_setup_entry(
|
|||
"""Set up Elgato Light based on a config entry."""
|
||||
data: HomeAssistantElgatoData = hass.data[DOMAIN][entry.entry_id]
|
||||
settings = await data.client.settings()
|
||||
async_add_entities([ElgatoLight(data.client, data.info, settings)], True)
|
||||
async_add_entities(
|
||||
[ElgatoLight(data.client, data.info, entry.data.get(CONF_MAC), settings)], True
|
||||
)
|
||||
|
||||
platform = async_get_current_platform()
|
||||
platform.async_register_entity_service(
|
||||
|
@ -53,9 +56,11 @@ async def async_setup_entry(
|
|||
class ElgatoLight(ElgatoEntity, LightEntity):
|
||||
"""Defines an Elgato Light."""
|
||||
|
||||
def __init__(self, client: Elgato, info: Info, settings: Settings) -> None:
|
||||
def __init__(
|
||||
self, client: Elgato, info: Info, mac: str | None, settings: Settings
|
||||
) -> None:
|
||||
"""Initialize Elgato Light."""
|
||||
super().__init__(client, info)
|
||||
super().__init__(client, info, mac)
|
||||
self._state: State | None = None
|
||||
|
||||
min_mired = 143
|
||||
|
|
|
@ -6,7 +6,7 @@ from elgato import Info, Settings, State
|
|||
import pytest
|
||||
|
||||
from homeassistant.components.elgato.const import DOMAIN
|
||||
from homeassistant.const import CONF_HOST, CONF_PORT
|
||||
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_PORT
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from tests.common import MockConfigEntry, load_fixture
|
||||
|
@ -19,7 +19,11 @@ def mock_config_entry() -> MockConfigEntry:
|
|||
return MockConfigEntry(
|
||||
title="CN11A1A00001",
|
||||
domain=DOMAIN,
|
||||
data={CONF_HOST: "127.0.0.1", CONF_PORT: 9123},
|
||||
data={
|
||||
CONF_HOST: "127.0.0.1",
|
||||
CONF_MAC: "AA:BB:CC:DD:EE:FF",
|
||||
CONF_PORT: 9123,
|
||||
},
|
||||
unique_id="CN11A1A00001",
|
||||
)
|
||||
|
||||
|
|
|
@ -5,9 +5,10 @@ from elgato import ElgatoError
|
|||
import pytest
|
||||
|
||||
from homeassistant.components.button import DOMAIN as BUTTON_DOMAIN, SERVICE_PRESS
|
||||
from homeassistant.components.elgato.const import DOMAIN
|
||||
from homeassistant.const import ATTR_ENTITY_ID, ATTR_ICON, STATE_UNKNOWN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
from homeassistant.helpers.entity import EntityCategory
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
@ -20,6 +21,7 @@ async def test_button_identify(
|
|||
mock_elgato: MagicMock,
|
||||
) -> None:
|
||||
"""Test the Elgato identify button."""
|
||||
device_registry = dr.async_get(hass)
|
||||
entity_registry = er.async_get(hass)
|
||||
|
||||
state = hass.states.get("button.identify")
|
||||
|
@ -32,6 +34,20 @@ async def test_button_identify(
|
|||
assert entry.unique_id == "CN11A1A00001_identify"
|
||||
assert entry.entity_category == EntityCategory.CONFIG
|
||||
|
||||
assert entry.device_id
|
||||
device_entry = device_registry.async_get(entry.device_id)
|
||||
assert device_entry
|
||||
assert device_entry.configuration_url is None
|
||||
assert device_entry.connections == {
|
||||
(dr.CONNECTION_NETWORK_MAC, "aa:bb:cc:dd:ee:ff")
|
||||
}
|
||||
assert device_entry.entry_type is None
|
||||
assert device_entry.identifiers == {(DOMAIN, "CN11A1A00001")}
|
||||
assert device_entry.manufacturer == "Elgato"
|
||||
assert device_entry.model == "Elgato Key Light"
|
||||
assert device_entry.name == "Frenck"
|
||||
assert device_entry.sw_version == "1.0.3 (192)"
|
||||
|
||||
await hass.services.async_call(
|
||||
BUTTON_DOMAIN,
|
||||
SERVICE_PRESS,
|
||||
|
|
|
@ -6,7 +6,7 @@ from elgato import ElgatoConnectionError
|
|||
from homeassistant.components import zeroconf
|
||||
from homeassistant.components.elgato.const import DOMAIN
|
||||
from homeassistant.config_entries import SOURCE_USER, SOURCE_ZEROCONF
|
||||
from homeassistant.const import CONF_HOST, CONF_PORT, CONF_SOURCE
|
||||
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_PORT, CONF_SOURCE
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import (
|
||||
RESULT_TYPE_ABORT,
|
||||
|
@ -40,6 +40,7 @@ async def test_full_user_flow_implementation(
|
|||
assert result2.get("title") == "CN11A1A00001"
|
||||
assert result2.get("data") == {
|
||||
CONF_HOST: "127.0.0.1",
|
||||
CONF_MAC: None,
|
||||
CONF_PORT: 9123,
|
||||
}
|
||||
assert "result" in result2
|
||||
|
@ -63,7 +64,7 @@ async def test_full_zeroconf_flow_implementation(
|
|||
hostname="example.local.",
|
||||
name="mock_name",
|
||||
port=9123,
|
||||
properties={},
|
||||
properties={"id": "AA:BB:CC:DD:EE:FF"},
|
||||
type="mock_type",
|
||||
),
|
||||
)
|
||||
|
@ -87,6 +88,7 @@ async def test_full_zeroconf_flow_implementation(
|
|||
assert result2.get("title") == "CN11A1A00001"
|
||||
assert result2.get("data") == {
|
||||
CONF_HOST: "127.0.0.1",
|
||||
CONF_MAC: "AA:BB:CC:DD:EE:FF",
|
||||
CONF_PORT: 9123,
|
||||
}
|
||||
assert "result" in result2
|
||||
|
|
|
@ -25,7 +25,7 @@ from homeassistant.const import (
|
|||
STATE_UNAVAILABLE,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
@ -36,6 +36,7 @@ async def test_light_state_temperature(
|
|||
mock_elgato: MagicMock,
|
||||
) -> None:
|
||||
"""Test the creation and values of the Elgato Lights in temperature mode."""
|
||||
device_registry = dr.async_get(hass)
|
||||
entity_registry = er.async_get(hass)
|
||||
|
||||
# First segment of the strip
|
||||
|
@ -54,6 +55,20 @@ async def test_light_state_temperature(
|
|||
assert entry
|
||||
assert entry.unique_id == "CN11A1A00001"
|
||||
|
||||
assert entry.device_id
|
||||
device_entry = device_registry.async_get(entry.device_id)
|
||||
assert device_entry
|
||||
assert device_entry.configuration_url is None
|
||||
assert device_entry.connections == {
|
||||
(dr.CONNECTION_NETWORK_MAC, "aa:bb:cc:dd:ee:ff")
|
||||
}
|
||||
assert device_entry.entry_type is None
|
||||
assert device_entry.identifiers == {(DOMAIN, "CN11A1A00001")}
|
||||
assert device_entry.manufacturer == "Elgato"
|
||||
assert device_entry.model == "Elgato Key Light"
|
||||
assert device_entry.name == "Frenck"
|
||||
assert device_entry.sw_version == "1.0.3 (192)"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"mock_elgato", [{"settings": "color", "state": "color"}], indirect=True
|
||||
|
|
Loading…
Reference in New Issue