Migrate Melcloud to has entity name (#99025)

This commit is contained in:
ollo69 2023-08-30 10:53:52 +02:00 committed by GitHub
parent e7462e916a
commit a89a5f486d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 67 additions and 48 deletions

View file

@ -8,6 +8,7 @@ from typing import Any
from aiohttp import ClientConnectionError from aiohttp import ClientConnectionError
from pymelcloud import Device, get_devices from pymelcloud import Device, get_devices
from pymelcloud.atw_device import Zone
import voluptuous as vol import voluptuous as vol
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
@ -139,6 +140,17 @@ class MelCloudDevice:
name=self.name, name=self.name,
) )
def zone_device_info(self, zone: Zone) -> DeviceInfo:
"""Return a zone device description for device registry."""
dev = self.device
return DeviceInfo(
identifiers={(DOMAIN, f"{dev.mac}-{dev.serial}-{zone.zone_index}")},
manufacturer="Mitsubishi Electric",
model="ATW zone device",
name=f"{self.name} {zone.name}",
via_device=(DOMAIN, f"{dev.mac}-{dev.serial}"),
)
@property @property
def daily_energy_consumed(self) -> float | None: def daily_energy_consumed(self) -> float | None:
"""Return energy consumed during the current day in kWh.""" """Return energy consumed during the current day in kWh."""

View file

@ -99,6 +99,8 @@ class MelCloudClimate(ClimateEntity):
"""Base climate device.""" """Base climate device."""
_attr_temperature_unit = UnitOfTemperature.CELSIUS _attr_temperature_unit = UnitOfTemperature.CELSIUS
_attr_has_entity_name = True
_attr_name = None
def __init__(self, device: MelCloudDevice) -> None: def __init__(self, device: MelCloudDevice) -> None:
"""Initialize the climate.""" """Initialize the climate."""
@ -109,11 +111,6 @@ class MelCloudClimate(ClimateEntity):
"""Update state from MELCloud.""" """Update state from MELCloud."""
await self.api.async_update() await self.api.async_update()
@property
def device_info(self):
"""Return a device description for device registry."""
return self.api.device_info
@property @property
def target_temperature_step(self) -> float | None: def target_temperature_step(self) -> float | None:
"""Return the supported step of target temperature.""" """Return the supported step of target temperature."""
@ -134,8 +131,8 @@ class AtaDeviceClimate(MelCloudClimate):
super().__init__(device) super().__init__(device)
self._device = ata_device self._device = ata_device
self._attr_name = device.name
self._attr_unique_id = f"{self.api.device.serial}-{self.api.device.mac}" self._attr_unique_id = f"{self.api.device.serial}-{self.api.device.mac}"
self._attr_device_info = self.api.device_info
@property @property
def extra_state_attributes(self) -> dict[str, Any] | None: def extra_state_attributes(self) -> dict[str, Any] | None:
@ -310,8 +307,8 @@ class AtwDeviceZoneClimate(MelCloudClimate):
self._device = atw_device self._device = atw_device
self._zone = atw_zone self._zone = atw_zone
self._attr_name = f"{device.name} {self._zone.name}"
self._attr_unique_id = f"{self.api.device.serial}-{atw_zone.zone_index}" self._attr_unique_id = f"{self.api.device.serial}-{atw_zone.zone_index}"
self._attr_device_info = self.api.zone_device_info(atw_zone)
@property @property
def extra_state_attributes(self) -> dict[str, Any]: def extra_state_attributes(self) -> dict[str, Any]:

View file

@ -41,28 +41,30 @@ class MelcloudSensorEntityDescription(
ATA_SENSORS: tuple[MelcloudSensorEntityDescription, ...] = ( ATA_SENSORS: tuple[MelcloudSensorEntityDescription, ...] = (
MelcloudSensorEntityDescription( MelcloudSensorEntityDescription(
key="room_temperature", key="room_temperature",
name="Room Temperature", translation_key="room_temperature",
icon="mdi:thermometer", icon="mdi:thermometer",
native_unit_of_measurement=UnitOfTemperature.CELSIUS, native_unit_of_measurement=UnitOfTemperature.CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE, device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda x: x.device.room_temperature, value_fn=lambda x: x.device.room_temperature,
enabled=lambda x: True, enabled=lambda x: True,
), ),
MelcloudSensorEntityDescription( MelcloudSensorEntityDescription(
key="energy", key="energy",
name="Energy",
icon="mdi:factory", icon="mdi:factory",
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
device_class=SensorDeviceClass.ENERGY, device_class=SensorDeviceClass.ENERGY,
state_class=SensorStateClass.TOTAL_INCREASING,
value_fn=lambda x: x.device.total_energy_consumed, value_fn=lambda x: x.device.total_energy_consumed,
enabled=lambda x: x.device.has_energy_consumed_meter, enabled=lambda x: x.device.has_energy_consumed_meter,
), ),
MelcloudSensorEntityDescription( MelcloudSensorEntityDescription(
key="daily_energy", key="daily_energy",
name="Daily Energy Consumed", translation_key="daily_energy",
icon="mdi:factory", icon="mdi:factory",
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
device_class=SensorDeviceClass.ENERGY, device_class=SensorDeviceClass.ENERGY,
state_class=SensorStateClass.TOTAL_INCREASING,
value_fn=lambda x: x.device.daily_energy_consumed, value_fn=lambda x: x.device.daily_energy_consumed,
enabled=lambda x: True, enabled=lambda x: True,
), ),
@ -70,28 +72,31 @@ ATA_SENSORS: tuple[MelcloudSensorEntityDescription, ...] = (
ATW_SENSORS: tuple[MelcloudSensorEntityDescription, ...] = ( ATW_SENSORS: tuple[MelcloudSensorEntityDescription, ...] = (
MelcloudSensorEntityDescription( MelcloudSensorEntityDescription(
key="outside_temperature", key="outside_temperature",
name="Outside Temperature", translation_key="outside_temperature",
icon="mdi:thermometer", icon="mdi:thermometer",
native_unit_of_measurement=UnitOfTemperature.CELSIUS, native_unit_of_measurement=UnitOfTemperature.CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE, device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda x: x.device.outside_temperature, value_fn=lambda x: x.device.outside_temperature,
enabled=lambda x: True, enabled=lambda x: True,
), ),
MelcloudSensorEntityDescription( MelcloudSensorEntityDescription(
key="tank_temperature", key="tank_temperature",
name="Tank Temperature", translation_key="tank_temperature",
icon="mdi:thermometer", icon="mdi:thermometer",
native_unit_of_measurement=UnitOfTemperature.CELSIUS, native_unit_of_measurement=UnitOfTemperature.CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE, device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda x: x.device.tank_temperature, value_fn=lambda x: x.device.tank_temperature,
enabled=lambda x: True, enabled=lambda x: True,
), ),
MelcloudSensorEntityDescription( MelcloudSensorEntityDescription(
key="daily_energy", key="daily_energy",
name="Daily Energy Consumed", translation_key="daily_energy",
icon="mdi:factory", icon="mdi:factory",
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
device_class=SensorDeviceClass.ENERGY, device_class=SensorDeviceClass.ENERGY,
state_class=SensorStateClass.TOTAL_INCREASING,
value_fn=lambda x: x.device.daily_energy_consumed, value_fn=lambda x: x.device.daily_energy_consumed,
enabled=lambda x: True, enabled=lambda x: True,
), ),
@ -99,28 +104,31 @@ ATW_SENSORS: tuple[MelcloudSensorEntityDescription, ...] = (
ATW_ZONE_SENSORS: tuple[MelcloudSensorEntityDescription, ...] = ( ATW_ZONE_SENSORS: tuple[MelcloudSensorEntityDescription, ...] = (
MelcloudSensorEntityDescription( MelcloudSensorEntityDescription(
key="room_temperature", key="room_temperature",
name="Room Temperature", translation_key="room_temperature",
icon="mdi:thermometer", icon="mdi:thermometer",
native_unit_of_measurement=UnitOfTemperature.CELSIUS, native_unit_of_measurement=UnitOfTemperature.CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE, device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda zone: zone.room_temperature, value_fn=lambda zone: zone.room_temperature,
enabled=lambda x: True, enabled=lambda x: True,
), ),
MelcloudSensorEntityDescription( MelcloudSensorEntityDescription(
key="flow_temperature", key="flow_temperature",
name="Flow Temperature", translation_key="flow_temperature",
icon="mdi:thermometer", icon="mdi:thermometer",
native_unit_of_measurement=UnitOfTemperature.CELSIUS, native_unit_of_measurement=UnitOfTemperature.CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE, device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda zone: zone.flow_temperature, value_fn=lambda zone: zone.flow_temperature,
enabled=lambda x: True, enabled=lambda x: True,
), ),
MelcloudSensorEntityDescription( MelcloudSensorEntityDescription(
key="return_temperature", key="return_temperature",
name="Flow Return Temperature", translation_key="return_temperature",
icon="mdi:thermometer", icon="mdi:thermometer",
native_unit_of_measurement=UnitOfTemperature.CELSIUS, native_unit_of_measurement=UnitOfTemperature.CELSIUS,
device_class=SensorDeviceClass.TEMPERATURE, device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda zone: zone.return_temperature, value_fn=lambda zone: zone.return_temperature,
enabled=lambda x: True, enabled=lambda x: True,
), ),
@ -160,6 +168,7 @@ class MelDeviceSensor(SensorEntity):
"""Representation of a Sensor.""" """Representation of a Sensor."""
entity_description: MelcloudSensorEntityDescription entity_description: MelcloudSensorEntityDescription
_attr_has_entity_name = True
def __init__( def __init__(
self, self,
@ -170,16 +179,11 @@ class MelDeviceSensor(SensorEntity):
self._api = api self._api = api
self.entity_description = description self.entity_description = description
self._attr_name = f"{api.name} {description.name}"
self._attr_unique_id = f"{api.device.serial}-{api.device.mac}-{description.key}" self._attr_unique_id = f"{api.device.serial}-{api.device.mac}-{description.key}"
self._attr_device_info = api.device_info
if description.device_class == SensorDeviceClass.ENERGY:
self._attr_state_class = SensorStateClass.TOTAL_INCREASING
else:
self._attr_state_class = SensorStateClass.MEASUREMENT
@property @property
def native_value(self): def native_value(self) -> float | None:
"""Return the state of the sensor.""" """Return the state of the sensor."""
return self.entity_description.value_fn(self._api) return self.entity_description.value_fn(self._api)
@ -187,11 +191,6 @@ class MelDeviceSensor(SensorEntity):
"""Retrieve latest state.""" """Retrieve latest state."""
await self._api.async_update() await self._api.async_update()
@property
def device_info(self):
"""Return a device description for device registry."""
return self._api.device_info
class AtwZoneSensor(MelDeviceSensor): class AtwZoneSensor(MelDeviceSensor):
"""Air-to-Air device sensor.""" """Air-to-Air device sensor."""
@ -206,10 +205,11 @@ class AtwZoneSensor(MelDeviceSensor):
if zone.zone_index != 1: if zone.zone_index != 1:
description.key = f"{description.key}-zone-{zone.zone_index}" description.key = f"{description.key}-zone-{zone.zone_index}"
super().__init__(api, description) super().__init__(api, description)
self._attr_device_info = api.zone_device_info(zone)
self._zone = zone self._zone = zone
self._attr_name = f"{api.name} {zone.name} {description.name}"
@property @property
def native_value(self): def native_value(self) -> float | None:
"""Return zone based state.""" """Return zone based state."""
return self.entity_description.value_fn(self._zone) return self.entity_description.value_fn(self._zone)

View file

@ -50,5 +50,27 @@
"title": "The MELCloud YAML configuration import failed", "title": "The MELCloud YAML configuration import failed",
"description": "Configuring MELCloud using YAML is being removed but there was an connection error importing your YAML configuration.\n\nEnsure connection to MELCloud works and restart Home Assistant to try again or remove the MELCloud YAML configuration from your configuration.yaml file and continue to [set up the integration](/config/integrations/dashboard/add?domain=melcoud) manually." "description": "Configuring MELCloud using YAML is being removed but there was an connection error importing your YAML configuration.\n\nEnsure connection to MELCloud works and restart Home Assistant to try again or remove the MELCloud YAML configuration from your configuration.yaml file and continue to [set up the integration](/config/integrations/dashboard/add?domain=melcoud) manually."
} }
},
"entity": {
"sensor": {
"room_temperature": {
"name": "Room temperature"
},
"daily_energy": {
"name": "Daily energy consumed"
},
"outside_temperature": {
"name": "Outside temperature"
},
"tank_temperature": {
"name": "Tank temperature"
},
"flow_temperature": {
"name": "Flow temperature"
},
"return_temperature": {
"name": "Flow return temperature"
}
}
} }
} }

View file

@ -47,32 +47,20 @@ class AtwWaterHeater(WaterHeaterEntity):
| WaterHeaterEntityFeature.ON_OFF | WaterHeaterEntityFeature.ON_OFF
| WaterHeaterEntityFeature.OPERATION_MODE | WaterHeaterEntityFeature.OPERATION_MODE
) )
_attr_has_entity_name = True
_attr_name = None
def __init__(self, api: MelCloudDevice, device: AtwDevice) -> None: def __init__(self, api: MelCloudDevice, device: AtwDevice) -> None:
"""Initialize water heater device.""" """Initialize water heater device."""
self._api = api self._api = api
self._device = device self._device = device
self._name = device.name self._attr_unique_id = api.device.serial
self._attr_device_info = api.device_info
async def async_update(self) -> None: async def async_update(self) -> None:
"""Update state from MELCloud.""" """Update state from MELCloud."""
await self._api.async_update() await self._api.async_update()
@property
def unique_id(self) -> str | None:
"""Return a unique ID."""
return f"{self._api.device.serial}"
@property
def name(self):
"""Return the display name of this entity."""
return self._name
@property
def device_info(self):
"""Return a device description for device registry."""
return self._api.device_info
async def async_turn_on(self, **kwargs: Any) -> None: async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the entity on.""" """Turn the entity on."""
await self._device.set({PROPERTY_POWER: True}) await self._device.set({PROPERTY_POWER: True})
@ -82,7 +70,7 @@ class AtwWaterHeater(WaterHeaterEntity):
await self._device.set({PROPERTY_POWER: False}) await self._device.set({PROPERTY_POWER: False})
@property @property
def extra_state_attributes(self): def extra_state_attributes(self) -> dict[str, Any] | None:
"""Return the optional state attributes with device specific additions.""" """Return the optional state attributes with device specific additions."""
data = {ATTR_STATUS: self._device.status} data = {ATTR_STATUS: self._device.status}
return data return data
@ -108,7 +96,7 @@ class AtwWaterHeater(WaterHeaterEntity):
return self._device.tank_temperature return self._device.tank_temperature
@property @property
def target_temperature(self): def target_temperature(self) -> float | None:
"""Return the temperature we try to reach.""" """Return the temperature we try to reach."""
return self._device.target_tank_temperature return self._device.target_tank_temperature