From a89a5f486d840b71b2430c13830f6f1513cae821 Mon Sep 17 00:00:00 2001 From: ollo69 <60491700+ollo69@users.noreply.github.com> Date: Wed, 30 Aug 2023 10:53:52 +0200 Subject: [PATCH] Migrate Melcloud to has entity name (#99025) --- homeassistant/components/melcloud/__init__.py | 12 +++++ homeassistant/components/melcloud/climate.py | 11 ++--- homeassistant/components/melcloud/sensor.py | 46 +++++++++---------- .../components/melcloud/strings.json | 22 +++++++++ .../components/melcloud/water_heater.py | 24 +++------- 5 files changed, 67 insertions(+), 48 deletions(-) diff --git a/homeassistant/components/melcloud/__init__.py b/homeassistant/components/melcloud/__init__.py index 68b40d8567f..5f007f3a8e5 100644 --- a/homeassistant/components/melcloud/__init__.py +++ b/homeassistant/components/melcloud/__init__.py @@ -8,6 +8,7 @@ from typing import Any from aiohttp import ClientConnectionError from pymelcloud import Device, get_devices +from pymelcloud.atw_device import Zone import voluptuous as vol from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry @@ -139,6 +140,17 @@ class MelCloudDevice: 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 def daily_energy_consumed(self) -> float | None: """Return energy consumed during the current day in kWh.""" diff --git a/homeassistant/components/melcloud/climate.py b/homeassistant/components/melcloud/climate.py index 2cac1abcf88..589223dc0f3 100644 --- a/homeassistant/components/melcloud/climate.py +++ b/homeassistant/components/melcloud/climate.py @@ -99,6 +99,8 @@ class MelCloudClimate(ClimateEntity): """Base climate device.""" _attr_temperature_unit = UnitOfTemperature.CELSIUS + _attr_has_entity_name = True + _attr_name = None def __init__(self, device: MelCloudDevice) -> None: """Initialize the climate.""" @@ -109,11 +111,6 @@ class MelCloudClimate(ClimateEntity): """Update state from MELCloud.""" await self.api.async_update() - @property - def device_info(self): - """Return a device description for device registry.""" - return self.api.device_info - @property def target_temperature_step(self) -> float | None: """Return the supported step of target temperature.""" @@ -134,8 +131,8 @@ class AtaDeviceClimate(MelCloudClimate): super().__init__(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_device_info = self.api.device_info @property def extra_state_attributes(self) -> dict[str, Any] | None: @@ -310,8 +307,8 @@ class AtwDeviceZoneClimate(MelCloudClimate): self._device = atw_device 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_device_info = self.api.zone_device_info(atw_zone) @property def extra_state_attributes(self) -> dict[str, Any]: diff --git a/homeassistant/components/melcloud/sensor.py b/homeassistant/components/melcloud/sensor.py index 74187948d7d..ca02d15db01 100644 --- a/homeassistant/components/melcloud/sensor.py +++ b/homeassistant/components/melcloud/sensor.py @@ -41,28 +41,30 @@ class MelcloudSensorEntityDescription( ATA_SENSORS: tuple[MelcloudSensorEntityDescription, ...] = ( MelcloudSensorEntityDescription( key="room_temperature", - name="Room Temperature", + translation_key="room_temperature", icon="mdi:thermometer", native_unit_of_measurement=UnitOfTemperature.CELSIUS, device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, value_fn=lambda x: x.device.room_temperature, enabled=lambda x: True, ), MelcloudSensorEntityDescription( key="energy", - name="Energy", icon="mdi:factory", native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL_INCREASING, value_fn=lambda x: x.device.total_energy_consumed, enabled=lambda x: x.device.has_energy_consumed_meter, ), MelcloudSensorEntityDescription( key="daily_energy", - name="Daily Energy Consumed", + translation_key="daily_energy", icon="mdi:factory", native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL_INCREASING, value_fn=lambda x: x.device.daily_energy_consumed, enabled=lambda x: True, ), @@ -70,28 +72,31 @@ ATA_SENSORS: tuple[MelcloudSensorEntityDescription, ...] = ( ATW_SENSORS: tuple[MelcloudSensorEntityDescription, ...] = ( MelcloudSensorEntityDescription( key="outside_temperature", - name="Outside Temperature", + translation_key="outside_temperature", icon="mdi:thermometer", native_unit_of_measurement=UnitOfTemperature.CELSIUS, device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, value_fn=lambda x: x.device.outside_temperature, enabled=lambda x: True, ), MelcloudSensorEntityDescription( key="tank_temperature", - name="Tank Temperature", + translation_key="tank_temperature", icon="mdi:thermometer", native_unit_of_measurement=UnitOfTemperature.CELSIUS, device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, value_fn=lambda x: x.device.tank_temperature, enabled=lambda x: True, ), MelcloudSensorEntityDescription( key="daily_energy", - name="Daily Energy Consumed", + translation_key="daily_energy", icon="mdi:factory", native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR, device_class=SensorDeviceClass.ENERGY, + state_class=SensorStateClass.TOTAL_INCREASING, value_fn=lambda x: x.device.daily_energy_consumed, enabled=lambda x: True, ), @@ -99,28 +104,31 @@ ATW_SENSORS: tuple[MelcloudSensorEntityDescription, ...] = ( ATW_ZONE_SENSORS: tuple[MelcloudSensorEntityDescription, ...] = ( MelcloudSensorEntityDescription( key="room_temperature", - name="Room Temperature", + translation_key="room_temperature", icon="mdi:thermometer", native_unit_of_measurement=UnitOfTemperature.CELSIUS, device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, value_fn=lambda zone: zone.room_temperature, enabled=lambda x: True, ), MelcloudSensorEntityDescription( key="flow_temperature", - name="Flow Temperature", + translation_key="flow_temperature", icon="mdi:thermometer", native_unit_of_measurement=UnitOfTemperature.CELSIUS, device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, value_fn=lambda zone: zone.flow_temperature, enabled=lambda x: True, ), MelcloudSensorEntityDescription( key="return_temperature", - name="Flow Return Temperature", + translation_key="return_temperature", icon="mdi:thermometer", native_unit_of_measurement=UnitOfTemperature.CELSIUS, device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, value_fn=lambda zone: zone.return_temperature, enabled=lambda x: True, ), @@ -160,6 +168,7 @@ class MelDeviceSensor(SensorEntity): """Representation of a Sensor.""" entity_description: MelcloudSensorEntityDescription + _attr_has_entity_name = True def __init__( self, @@ -170,16 +179,11 @@ class MelDeviceSensor(SensorEntity): self._api = api 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}" - - if description.device_class == SensorDeviceClass.ENERGY: - self._attr_state_class = SensorStateClass.TOTAL_INCREASING - else: - self._attr_state_class = SensorStateClass.MEASUREMENT + self._attr_device_info = api.device_info @property - def native_value(self): + def native_value(self) -> float | None: """Return the state of the sensor.""" return self.entity_description.value_fn(self._api) @@ -187,11 +191,6 @@ class MelDeviceSensor(SensorEntity): """Retrieve latest state.""" 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): """Air-to-Air device sensor.""" @@ -206,10 +205,11 @@ class AtwZoneSensor(MelDeviceSensor): if zone.zone_index != 1: description.key = f"{description.key}-zone-{zone.zone_index}" super().__init__(api, description) + + self._attr_device_info = api.zone_device_info(zone) self._zone = zone - self._attr_name = f"{api.name} {zone.name} {description.name}" @property - def native_value(self): + def native_value(self) -> float | None: """Return zone based state.""" return self.entity_description.value_fn(self._zone) diff --git a/homeassistant/components/melcloud/strings.json b/homeassistant/components/melcloud/strings.json index 23c1c63d328..eefd5a07a8d 100644 --- a/homeassistant/components/melcloud/strings.json +++ b/homeassistant/components/melcloud/strings.json @@ -50,5 +50,27 @@ "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." } + }, + "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" + } + } } } diff --git a/homeassistant/components/melcloud/water_heater.py b/homeassistant/components/melcloud/water_heater.py index cf4b788480f..210b8bd51e2 100644 --- a/homeassistant/components/melcloud/water_heater.py +++ b/homeassistant/components/melcloud/water_heater.py @@ -47,32 +47,20 @@ class AtwWaterHeater(WaterHeaterEntity): | WaterHeaterEntityFeature.ON_OFF | WaterHeaterEntityFeature.OPERATION_MODE ) + _attr_has_entity_name = True + _attr_name = None def __init__(self, api: MelCloudDevice, device: AtwDevice) -> None: """Initialize water heater device.""" self._api = api 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: """Update state from MELCloud.""" 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: """Turn the entity on.""" await self._device.set({PROPERTY_POWER: True}) @@ -82,7 +70,7 @@ class AtwWaterHeater(WaterHeaterEntity): await self._device.set({PROPERTY_POWER: False}) @property - def extra_state_attributes(self): + def extra_state_attributes(self) -> dict[str, Any] | None: """Return the optional state attributes with device specific additions.""" data = {ATTR_STATUS: self._device.status} return data @@ -108,7 +96,7 @@ class AtwWaterHeater(WaterHeaterEntity): return self._device.tank_temperature @property - def target_temperature(self): + def target_temperature(self) -> float | None: """Return the temperature we try to reach.""" return self._device.target_tank_temperature