mirror of
https://github.com/home-assistant/core.git
synced 2025-07-10 14:57:09 +00:00
Migrate devolo Home Control to new entity naming (#74969)
This commit is contained in:
parent
e4c73259f7
commit
1e64d830ac
@ -81,13 +81,14 @@ class DevoloBinaryDeviceEntity(DevoloDeviceEntity, BinarySensorEntity):
|
|||||||
or self._binary_sensor_property.sensor_type
|
or self._binary_sensor_property.sensor_type
|
||||||
)
|
)
|
||||||
|
|
||||||
if self._attr_device_class is None:
|
|
||||||
if device_instance.binary_sensor_property[element_uid].sub_type != "":
|
if device_instance.binary_sensor_property[element_uid].sub_type != "":
|
||||||
self._attr_name += (
|
self._attr_name = device_instance.binary_sensor_property[
|
||||||
f" {device_instance.binary_sensor_property[element_uid].sub_type}"
|
element_uid
|
||||||
)
|
].sub_type.capitalize()
|
||||||
else:
|
else:
|
||||||
self._attr_name += f" {device_instance.binary_sensor_property[element_uid].sensor_type}"
|
self._attr_name = device_instance.binary_sensor_property[
|
||||||
|
element_uid
|
||||||
|
].sensor_type.capitalize()
|
||||||
|
|
||||||
self._value = self._binary_sensor_property.state
|
self._value = self._binary_sensor_property.state
|
||||||
|
|
||||||
@ -128,6 +129,7 @@ class DevoloRemoteControl(DevoloDeviceEntity, BinarySensorEntity):
|
|||||||
|
|
||||||
self._key = key
|
self._key = key
|
||||||
self._attr_is_on = False
|
self._attr_is_on = False
|
||||||
|
self._attr_name = f"Button {key}"
|
||||||
|
|
||||||
def _sync(self, message: tuple) -> None:
|
def _sync(self, message: tuple) -> None:
|
||||||
"""Update the binary sensor state."""
|
"""Update the binary sensor state."""
|
||||||
|
@ -19,6 +19,8 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
class DevoloDeviceEntity(Entity):
|
class DevoloDeviceEntity(Entity):
|
||||||
"""Abstract representation of a device within devolo Home Control."""
|
"""Abstract representation of a device within devolo Home Control."""
|
||||||
|
|
||||||
|
_attr_has_entity_name = True
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, homecontrol: HomeControl, device_instance: Zwave, element_uid: str
|
self, homecontrol: HomeControl, device_instance: Zwave, element_uid: str
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -29,9 +31,6 @@ class DevoloDeviceEntity(Entity):
|
|||||||
self._attr_available = (
|
self._attr_available = (
|
||||||
device_instance.is_online()
|
device_instance.is_online()
|
||||||
) # This is not doing I/O. It fetches an internal state of the API
|
) # This is not doing I/O. It fetches an internal state of the API
|
||||||
self._attr_name: str = device_instance.settings_property[
|
|
||||||
"general_device_settings"
|
|
||||||
].name
|
|
||||||
self._attr_should_poll = False
|
self._attr_should_poll = False
|
||||||
self._attr_unique_id = element_uid
|
self._attr_unique_id = element_uid
|
||||||
self._attr_device_info = DeviceInfo(
|
self._attr_device_info = DeviceInfo(
|
||||||
@ -39,7 +38,7 @@ class DevoloDeviceEntity(Entity):
|
|||||||
identifiers={(DOMAIN, self._device_instance.uid)},
|
identifiers={(DOMAIN, self._device_instance.uid)},
|
||||||
manufacturer=device_instance.brand,
|
manufacturer=device_instance.brand,
|
||||||
model=device_instance.name,
|
model=device_instance.name,
|
||||||
name=self._attr_name,
|
name=device_instance.settings_property["general_device_settings"].name,
|
||||||
suggested_area=device_instance.settings_property[
|
suggested_area=device_instance.settings_property[
|
||||||
"general_device_settings"
|
"general_device_settings"
|
||||||
].zone,
|
].zone,
|
||||||
@ -47,11 +46,16 @@ class DevoloDeviceEntity(Entity):
|
|||||||
|
|
||||||
self.subscriber: Subscriber | None = None
|
self.subscriber: Subscriber | None = None
|
||||||
self.sync_callback = self._sync
|
self.sync_callback = self._sync
|
||||||
|
|
||||||
self._value: float
|
self._value: float
|
||||||
|
|
||||||
async def async_added_to_hass(self) -> None:
|
async def async_added_to_hass(self) -> None:
|
||||||
"""Call when entity is added to hass."""
|
"""Call when entity is added to hass."""
|
||||||
self.subscriber = Subscriber(self._attr_name, callback=self.sync_callback)
|
assert self.device_info
|
||||||
|
assert self.device_info["name"] # The name was set on entity creation
|
||||||
|
self.subscriber = Subscriber(
|
||||||
|
self.device_info["name"], callback=self.sync_callback
|
||||||
|
)
|
||||||
self._homecontrol.publisher.register(
|
self._homecontrol.publisher.register(
|
||||||
self._device_instance.uid, self.subscriber, self.sync_callback
|
self._device_instance.uid, self.subscriber, self.sync_callback
|
||||||
)
|
)
|
||||||
|
@ -115,12 +115,9 @@ class DevoloGenericMultiLevelDeviceEntity(DevoloMultiLevelDeviceEntity):
|
|||||||
self._multi_level_sensor_property.sensor_type
|
self._multi_level_sensor_property.sensor_type
|
||||||
)
|
)
|
||||||
self._attr_native_unit_of_measurement = self._multi_level_sensor_property.unit
|
self._attr_native_unit_of_measurement = self._multi_level_sensor_property.unit
|
||||||
|
self._attr_name = self._multi_level_sensor_property.sensor_type.capitalize()
|
||||||
self._value = self._multi_level_sensor_property.value
|
self._value = self._multi_level_sensor_property.value
|
||||||
|
|
||||||
if self._attr_device_class is None:
|
|
||||||
self._attr_name += f" {self._multi_level_sensor_property.sensor_type}"
|
|
||||||
|
|
||||||
if element_uid.startswith("devolo.VoltageMultiLevelSensor:"):
|
if element_uid.startswith("devolo.VoltageMultiLevelSensor:"):
|
||||||
self._attr_entity_registry_enabled_default = False
|
self._attr_entity_registry_enabled_default = False
|
||||||
|
|
||||||
@ -143,7 +140,7 @@ class DevoloBatteryEntity(DevoloMultiLevelDeviceEntity):
|
|||||||
self._attr_state_class = STATE_CLASS_MAPPING.get("battery")
|
self._attr_state_class = STATE_CLASS_MAPPING.get("battery")
|
||||||
self._attr_entity_category = EntityCategory.DIAGNOSTIC
|
self._attr_entity_category = EntityCategory.DIAGNOSTIC
|
||||||
self._attr_native_unit_of_measurement = PERCENTAGE
|
self._attr_native_unit_of_measurement = PERCENTAGE
|
||||||
|
self._attr_name = "Battery level"
|
||||||
self._value = device_instance.battery_level
|
self._value = device_instance.battery_level
|
||||||
|
|
||||||
|
|
||||||
@ -179,7 +176,7 @@ class DevoloConsumptionEntity(DevoloMultiLevelDeviceEntity):
|
|||||||
device_instance.consumption_property[element_uid], consumption
|
device_instance.consumption_property[element_uid], consumption
|
||||||
)
|
)
|
||||||
|
|
||||||
self._attr_name += f" {consumption}"
|
self._attr_name = f"{consumption.capitalize()} consumption"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def unique_id(self) -> str:
|
def unique_id(self) -> str:
|
||||||
|
@ -4,7 +4,12 @@ from unittest.mock import patch
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components.binary_sensor import DOMAIN
|
from homeassistant.components.binary_sensor import DOMAIN
|
||||||
from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNAVAILABLE
|
from homeassistant.const import (
|
||||||
|
ATTR_FRIENDLY_NAME,
|
||||||
|
STATE_OFF,
|
||||||
|
STATE_ON,
|
||||||
|
STATE_UNAVAILABLE,
|
||||||
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers import entity_registry
|
from homeassistant.helpers import entity_registry
|
||||||
from homeassistant.helpers.entity import EntityCategory
|
from homeassistant.helpers.entity import EntityCategory
|
||||||
@ -31,25 +36,30 @@ async def test_binary_sensor(hass: HomeAssistant):
|
|||||||
await hass.config_entries.async_setup(entry.entry_id)
|
await hass.config_entries.async_setup(entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
state = hass.states.get(f"{DOMAIN}.test")
|
state = hass.states.get(f"{DOMAIN}.test_door")
|
||||||
assert state is not None
|
assert state is not None
|
||||||
assert state.state == STATE_OFF
|
assert state.state == STATE_OFF
|
||||||
|
assert state.attributes[ATTR_FRIENDLY_NAME] == "Test Door"
|
||||||
|
|
||||||
state = hass.states.get(f"{DOMAIN}.test_2")
|
state = hass.states.get(f"{DOMAIN}.test_overload")
|
||||||
assert state is not None
|
assert state is not None
|
||||||
|
assert state.attributes[ATTR_FRIENDLY_NAME] == "Test Overload"
|
||||||
er = entity_registry.async_get(hass)
|
er = entity_registry.async_get(hass)
|
||||||
assert er.async_get(f"{DOMAIN}.test_2").entity_category == EntityCategory.DIAGNOSTIC
|
assert (
|
||||||
|
er.async_get(f"{DOMAIN}.test_overload").entity_category
|
||||||
|
== EntityCategory.DIAGNOSTIC
|
||||||
|
)
|
||||||
|
|
||||||
# Emulate websocket message: sensor turned on
|
# Emulate websocket message: sensor turned on
|
||||||
test_gateway.publisher.dispatch("Test", ("Test", True))
|
test_gateway.publisher.dispatch("Test", ("Test", True))
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert hass.states.get(f"{DOMAIN}.test").state == STATE_ON
|
assert hass.states.get(f"{DOMAIN}.test_door").state == STATE_ON
|
||||||
|
|
||||||
# Emulate websocket message: device went offline
|
# Emulate websocket message: device went offline
|
||||||
test_gateway.devices["Test"].status = 1
|
test_gateway.devices["Test"].status = 1
|
||||||
test_gateway.publisher.dispatch("Test", ("Status", False, "status"))
|
test_gateway.publisher.dispatch("Test", ("Status", False, "status"))
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert hass.states.get(f"{DOMAIN}.test").state == STATE_UNAVAILABLE
|
assert hass.states.get(f"{DOMAIN}.test_door").state == STATE_UNAVAILABLE
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("mock_zeroconf")
|
@pytest.mark.usefixtures("mock_zeroconf")
|
||||||
@ -65,25 +75,26 @@ async def test_remote_control(hass: HomeAssistant):
|
|||||||
await hass.config_entries.async_setup(entry.entry_id)
|
await hass.config_entries.async_setup(entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
state = hass.states.get(f"{DOMAIN}.test")
|
state = hass.states.get(f"{DOMAIN}.test_button_1")
|
||||||
assert state is not None
|
assert state is not None
|
||||||
assert state.state == STATE_OFF
|
assert state.state == STATE_OFF
|
||||||
|
assert state.attributes[ATTR_FRIENDLY_NAME] == "Test Button 1"
|
||||||
|
|
||||||
# Emulate websocket message: button pressed
|
# Emulate websocket message: button pressed
|
||||||
test_gateway.publisher.dispatch("Test", ("Test", 1))
|
test_gateway.publisher.dispatch("Test", ("Test", 1))
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert hass.states.get(f"{DOMAIN}.test").state == STATE_ON
|
assert hass.states.get(f"{DOMAIN}.test_button_1").state == STATE_ON
|
||||||
|
|
||||||
# Emulate websocket message: button released
|
# Emulate websocket message: button released
|
||||||
test_gateway.publisher.dispatch("Test", ("Test", 0))
|
test_gateway.publisher.dispatch("Test", ("Test", 0))
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert hass.states.get(f"{DOMAIN}.test").state == STATE_OFF
|
assert hass.states.get(f"{DOMAIN}.test_button_1").state == STATE_OFF
|
||||||
|
|
||||||
# Emulate websocket message: device went offline
|
# Emulate websocket message: device went offline
|
||||||
test_gateway.devices["Test"].status = 1
|
test_gateway.devices["Test"].status = 1
|
||||||
test_gateway.publisher.dispatch("Test", ("Status", False, "status"))
|
test_gateway.publisher.dispatch("Test", ("Status", False, "status"))
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert hass.states.get(f"{DOMAIN}.test").state == STATE_UNAVAILABLE
|
assert hass.states.get(f"{DOMAIN}.test_button_1").state == STATE_UNAVAILABLE
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("mock_zeroconf")
|
@pytest.mark.usefixtures("mock_zeroconf")
|
||||||
@ -97,7 +108,7 @@ async def test_disabled(hass: HomeAssistant):
|
|||||||
await hass.config_entries.async_setup(entry.entry_id)
|
await hass.config_entries.async_setup(entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert hass.states.get(f"{DOMAIN}.devolo.WarningBinaryFI:Test") is None
|
assert hass.states.get(f"{DOMAIN}.test_door") is None
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("mock_zeroconf")
|
@pytest.mark.usefixtures("mock_zeroconf")
|
||||||
@ -112,7 +123,7 @@ async def test_remove_from_hass(hass: HomeAssistant):
|
|||||||
await hass.config_entries.async_setup(entry.entry_id)
|
await hass.config_entries.async_setup(entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
state = hass.states.get(f"{DOMAIN}.test")
|
state = hass.states.get(f"{DOMAIN}.test_door")
|
||||||
assert state is not None
|
assert state is not None
|
||||||
await hass.config_entries.async_remove(entry.entry_id)
|
await hass.config_entries.async_remove(entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
@ -7,7 +7,12 @@ from homeassistant.components.climate import (
|
|||||||
SERVICE_SET_TEMPERATURE,
|
SERVICE_SET_TEMPERATURE,
|
||||||
HVACMode,
|
HVACMode,
|
||||||
)
|
)
|
||||||
from homeassistant.const import ATTR_ENTITY_ID, ATTR_TEMPERATURE, STATE_UNAVAILABLE
|
from homeassistant.const import (
|
||||||
|
ATTR_ENTITY_ID,
|
||||||
|
ATTR_FRIENDLY_NAME,
|
||||||
|
ATTR_TEMPERATURE,
|
||||||
|
STATE_UNAVAILABLE,
|
||||||
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from . import configure_integration
|
from . import configure_integration
|
||||||
@ -30,6 +35,7 @@ async def test_climate(hass: HomeAssistant):
|
|||||||
assert state is not None
|
assert state is not None
|
||||||
assert state.state == HVACMode.HEAT
|
assert state.state == HVACMode.HEAT
|
||||||
assert state.attributes[ATTR_TEMPERATURE] == test_gateway.devices["Test"].value
|
assert state.attributes[ATTR_TEMPERATURE] == test_gateway.devices["Test"].value
|
||||||
|
assert state.attributes[ATTR_FRIENDLY_NAME] == "Test"
|
||||||
|
|
||||||
# Emulate websocket message: temperature changed
|
# Emulate websocket message: temperature changed
|
||||||
test_gateway.publisher.dispatch("Test", ("Test", 21.0))
|
test_gateway.publisher.dispatch("Test", ("Test", 21.0))
|
||||||
|
@ -4,6 +4,7 @@ from unittest.mock import patch
|
|||||||
from homeassistant.components.cover import ATTR_CURRENT_POSITION, ATTR_POSITION, DOMAIN
|
from homeassistant.components.cover import ATTR_CURRENT_POSITION, ATTR_POSITION, DOMAIN
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_ENTITY_ID,
|
ATTR_ENTITY_ID,
|
||||||
|
ATTR_FRIENDLY_NAME,
|
||||||
SERVICE_CLOSE_COVER,
|
SERVICE_CLOSE_COVER,
|
||||||
SERVICE_OPEN_COVER,
|
SERVICE_OPEN_COVER,
|
||||||
SERVICE_SET_COVER_POSITION,
|
SERVICE_SET_COVER_POSITION,
|
||||||
@ -32,6 +33,7 @@ async def test_cover(hass: HomeAssistant):
|
|||||||
state = hass.states.get(f"{DOMAIN}.test")
|
state = hass.states.get(f"{DOMAIN}.test")
|
||||||
assert state is not None
|
assert state is not None
|
||||||
assert state.state == STATE_OPEN
|
assert state.state == STATE_OPEN
|
||||||
|
assert state.attributes[ATTR_FRIENDLY_NAME] == "Test"
|
||||||
assert (
|
assert (
|
||||||
state.attributes[ATTR_CURRENT_POSITION]
|
state.attributes[ATTR_CURRENT_POSITION]
|
||||||
== test_gateway.devices["Test"]
|
== test_gateway.devices["Test"]
|
||||||
|
@ -10,6 +10,7 @@ from homeassistant.components.light import (
|
|||||||
)
|
)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_ENTITY_ID,
|
ATTR_ENTITY_ID,
|
||||||
|
ATTR_FRIENDLY_NAME,
|
||||||
SERVICE_TURN_OFF,
|
SERVICE_TURN_OFF,
|
||||||
SERVICE_TURN_ON,
|
SERVICE_TURN_ON,
|
||||||
STATE_OFF,
|
STATE_OFF,
|
||||||
@ -36,6 +37,7 @@ async def test_light_without_binary_sensor(hass: HomeAssistant):
|
|||||||
state = hass.states.get(f"{DOMAIN}.test")
|
state = hass.states.get(f"{DOMAIN}.test")
|
||||||
assert state is not None
|
assert state is not None
|
||||||
assert state.state == STATE_ON
|
assert state.state == STATE_ON
|
||||||
|
assert state.attributes[ATTR_FRIENDLY_NAME] == "Test"
|
||||||
assert state.attributes[ATTR_COLOR_MODE] == ColorMode.BRIGHTNESS
|
assert state.attributes[ATTR_COLOR_MODE] == ColorMode.BRIGHTNESS
|
||||||
assert state.attributes[ATTR_SUPPORTED_COLOR_MODES] == [ColorMode.BRIGHTNESS]
|
assert state.attributes[ATTR_SUPPORTED_COLOR_MODES] == [ColorMode.BRIGHTNESS]
|
||||||
assert state.attributes[ATTR_BRIGHTNESS] == round(
|
assert state.attributes[ATTR_BRIGHTNESS] == round(
|
||||||
|
@ -4,7 +4,12 @@ from unittest.mock import patch
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components.siren import DOMAIN
|
from homeassistant.components.siren import DOMAIN
|
||||||
from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNAVAILABLE
|
from homeassistant.const import (
|
||||||
|
ATTR_FRIENDLY_NAME,
|
||||||
|
STATE_OFF,
|
||||||
|
STATE_ON,
|
||||||
|
STATE_UNAVAILABLE,
|
||||||
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from . import configure_integration
|
from . import configure_integration
|
||||||
@ -27,6 +32,7 @@ async def test_siren(hass: HomeAssistant):
|
|||||||
state = hass.states.get(f"{DOMAIN}.test")
|
state = hass.states.get(f"{DOMAIN}.test")
|
||||||
assert state is not None
|
assert state is not None
|
||||||
assert state.state == STATE_OFF
|
assert state.state == STATE_OFF
|
||||||
|
assert state.attributes[ATTR_FRIENDLY_NAME] == "Test"
|
||||||
|
|
||||||
# Emulate websocket message: sensor turned on
|
# Emulate websocket message: sensor turned on
|
||||||
test_gateway.publisher.dispatch("Test", ("devolo.SirenMultiLevelSwitch:Test", 1))
|
test_gateway.publisher.dispatch("Test", ("devolo.SirenMultiLevelSwitch:Test", 1))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user