From 8e64ae84787dd70e369d5f551efbf69b52a4f52a Mon Sep 17 00:00:00 2001 From: Diogo Gomes Date: Wed, 13 Apr 2022 22:58:15 +0100 Subject: [PATCH] Add unique_id to utility_meter sensors (#68596) Co-authored-by: epenet <6771947+epenet@users.noreply.github.com> Co-authored-by: Erik Montnemery --- .../components/utility_meter/__init__.py | 3 ++- .../components/utility_meter/select.py | 17 ++++++++++--- .../components/utility_meter/sensor.py | 12 +++++++-- tests/components/utility_meter/test_sensor.py | 25 +++++++++++++++++++ 4 files changed, 51 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/utility_meter/__init__.py b/homeassistant/components/utility_meter/__init__.py index 5cb4d6f7abb..095a5e2825e 100644 --- a/homeassistant/components/utility_meter/__init__.py +++ b/homeassistant/components/utility_meter/__init__.py @@ -8,7 +8,7 @@ import voluptuous as vol from homeassistant.components.select import DOMAIN as SELECT_DOMAIN from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN from homeassistant.config_entries import ConfigEntry -from homeassistant.const import ATTR_ENTITY_ID, CONF_NAME, Platform +from homeassistant.const import ATTR_ENTITY_ID, CONF_NAME, CONF_UNIQUE_ID, Platform from homeassistant.core import HomeAssistant, split_entity_id from homeassistant.helpers import discovery, entity_registry as er import homeassistant.helpers.config_validation as cv @@ -78,6 +78,7 @@ METER_CONFIG_SCHEMA = vol.Schema( { vol.Required(CONF_SOURCE_SENSOR): cv.entity_id, vol.Optional(CONF_NAME): cv.string, + vol.Optional(CONF_UNIQUE_ID): cv.string, vol.Optional(CONF_METER_TYPE): vol.In(METER_TYPES), vol.Optional(CONF_METER_OFFSET, default=DEFAULT_OFFSET): vol.All( cv.time_period, cv.positive_timedelta, max_28_days diff --git a/homeassistant/components/utility_meter/select.py b/homeassistant/components/utility_meter/select.py index b78eec5c4f9..008a0ff6120 100644 --- a/homeassistant/components/utility_meter/select.py +++ b/homeassistant/components/utility_meter/select.py @@ -13,7 +13,12 @@ from homeassistant.components.select.const import ( SERVICE_SELECT_OPTION, ) from homeassistant.config_entries import ConfigEntry -from homeassistant.const import ATTR_ENTITY_ID, ATTR_FRIENDLY_NAME, STATE_UNAVAILABLE +from homeassistant.const import ( + ATTR_ENTITY_ID, + ATTR_FRIENDLY_NAME, + CONF_UNIQUE_ID, + STATE_UNAVAILABLE, +) from homeassistant.core import Event, HomeAssistant, callback, split_entity_id from homeassistant.helpers import config_validation as cv from homeassistant.helpers.entity import Entity @@ -28,6 +33,7 @@ from .const import ( CONF_METER, CONF_TARIFFS, DATA_LEGACY_COMPONENT, + DATA_UTILITY, SERVICE_SELECT_NEXT_TARIFF, SERVICE_SELECT_TARIFF, TARIFF_ICON, @@ -66,13 +72,18 @@ async def async_setup_platform( return legacy_component = hass.data[DATA_LEGACY_COMPONENT] + meter: str = discovery_info[CONF_METER] + conf_meter_unique_id: str | None = hass.data[DATA_UTILITY][meter].get( + CONF_UNIQUE_ID + ) + async_add_entities( [ TariffSelect( discovery_info[CONF_METER], discovery_info[CONF_TARIFFS], legacy_component.async_add_entities, - None, + conf_meter_unique_id, ) ] ) @@ -136,7 +147,7 @@ class LegacyTariffSelect(Entity): def __init__(self, tracked_entity_id): """Initialize the entity.""" self._attr_icon = TARIFF_ICON - # Set name to influence enity_id + # Set name to influence entity_id self._attr_name = split_entity_id(tracked_entity_id)[1] self.tracked_entity_id = tracked_entity_id diff --git a/homeassistant/components/utility_meter/sensor.py b/homeassistant/components/utility_meter/sensor.py index f523f244ea2..f44c7a950a9 100644 --- a/homeassistant/components/utility_meter/sensor.py +++ b/homeassistant/components/utility_meter/sensor.py @@ -18,6 +18,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( ATTR_UNIT_OF_MEASUREMENT, CONF_NAME, + CONF_UNIQUE_ID, ENERGY_KILO_WATT_HOUR, ENERGY_WATT_HOUR, STATE_UNAVAILABLE, @@ -186,6 +187,13 @@ async def async_setup_platform( for conf in discovery_info.values(): meter = conf[CONF_METER] conf_meter_source = hass.data[DATA_UTILITY][meter][CONF_SOURCE_SENSOR] + conf_meter_unique_id = hass.data[DATA_UTILITY][meter].get(CONF_UNIQUE_ID) + conf_sensor_tariff = conf.get(CONF_TARIFF, "single_tariff") + conf_sensor_unique_id = ( + f"{conf_meter_unique_id}_{conf_sensor_tariff}" + if conf_meter_unique_id + else None + ) conf_meter_type = hass.data[DATA_UTILITY][meter].get(CONF_METER_TYPE) conf_meter_offset = hass.data[DATA_UTILITY][meter][CONF_METER_OFFSET] conf_meter_delta_values = hass.data[DATA_UTILITY][meter][ @@ -208,8 +216,8 @@ async def async_setup_platform( parent_meter=meter, source_entity=conf_meter_source, tariff_entity=conf_meter_tariff_entity, - tariff=conf.get(CONF_TARIFF), - unique_id=None, + tariff=conf_sensor_tariff, + unique_id=conf_sensor_unique_id, ) meters.append(meter_sensor) diff --git a/tests/components/utility_meter/test_sensor.py b/tests/components/utility_meter/test_sensor.py index 0c37a775715..4aa403d842d 100644 --- a/tests/components/utility_meter/test_sensor.py +++ b/tests/components/utility_meter/test_sensor.py @@ -38,6 +38,7 @@ from homeassistant.const import ( STATE_UNKNOWN, ) from homeassistant.core import CoreState, State +from homeassistant.helpers import entity_registry from homeassistant.setup import async_setup_component import homeassistant.util.dt as dt_util @@ -317,6 +318,30 @@ async def test_init(hass, yaml_config, config_entry_config): assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == ENERGY_KILO_WATT_HOUR +async def test_unique_id(hass): + """Test unique_id configuration option.""" + yaml_config = { + "utility_meter": { + "energy_bill": { + "name": "Provider A", + "unique_id": "1", + "source": "sensor.energy", + "tariffs": ["onpeak", "midpeak", "offpeak"], + } + } + } + assert await async_setup_component(hass, DOMAIN, yaml_config) + await hass.async_block_till_done() + + hass.bus.async_fire(EVENT_HOMEASSISTANT_START) + await hass.async_block_till_done() + + ent_reg = entity_registry.async_get(hass) + assert len(ent_reg.entities) == 4 + assert ent_reg.entities["select.energy_bill"].unique_id == "1" + assert ent_reg.entities["sensor.energy_bill_onpeak"].unique_id == "1_onpeak" + + @pytest.mark.parametrize( "yaml_config,config_entry_configs", (