From f50d47121e31935dc1f7c116f22b1ca9dd6b0b1c Mon Sep 17 00:00:00 2001 From: Diogo Gomes Date: Sun, 10 Sep 2023 14:29:38 +0100 Subject: [PATCH] Always update unit of measurement of the utility_meter on state change (#99102) --- .../components/utility_meter/sensor.py | 8 +++++ tests/components/utility_meter/test_sensor.py | 33 +++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/homeassistant/components/utility_meter/sensor.py b/homeassistant/components/utility_meter/sensor.py index f3e86136f5d..cd581d8c37f 100644 --- a/homeassistant/components/utility_meter/sensor.py +++ b/homeassistant/components/utility_meter/sensor.py @@ -17,6 +17,7 @@ from homeassistant.components.sensor import ( SensorExtraStoredData, SensorStateClass, ) +from homeassistant.components.sensor.recorder import _suggest_report_issue from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( ATTR_UNIT_OF_MEASUREMENT, @@ -484,6 +485,12 @@ class UtilityMeterSensor(RestoreSensor): DATA_TARIFF_SENSORS ]: sensor.start(new_state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)) + if self._unit_of_measurement is None: + _LOGGER.warning( + "Source sensor %s has no unit of measurement. Please %s", + self._sensor_source_id, + _suggest_report_issue(self.hass, self._sensor_source_id), + ) if ( adjustment := self.calculate_adjustment(old_state, new_state) @@ -491,6 +498,7 @@ class UtilityMeterSensor(RestoreSensor): # If net_consumption is off, the adjustment must be non-negative self._state += adjustment # type: ignore[operator] # self._state will be set to by the start function if it is None, therefore it always has a valid Decimal value at this line + self._unit_of_measurement = new_state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) self._last_valid_state = new_state_val self.async_write_ha_state() diff --git a/tests/components/utility_meter/test_sensor.py b/tests/components/utility_meter/test_sensor.py index b8f197a4dee..43d68d87362 100644 --- a/tests/components/utility_meter/test_sensor.py +++ b/tests/components/utility_meter/test_sensor.py @@ -1460,6 +1460,39 @@ def test_calculate_adjustment_invalid_new_state( assert "Invalid state unknown" in caplog.text +async def test_unit_of_measurement_missing_invalid_new_state( + hass: HomeAssistant, + caplog: pytest.LogCaptureFixture, +) -> None: + """Test that a suggestion is created when new_state is missing unit_of_measurement.""" + yaml_config = { + "utility_meter": { + "energy_bill": { + "source": "sensor.energy", + } + } + } + source_entity_id = yaml_config[DOMAIN]["energy_bill"]["source"] + + assert await async_setup_component(hass, DOMAIN, yaml_config) + await hass.async_block_till_done() + + hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED) + await hass.async_block_till_done() + + hass.states.async_set(source_entity_id, 4, {ATTR_UNIT_OF_MEASUREMENT: None}) + + await hass.async_block_till_done() + + state = hass.states.get("sensor.energy_bill") + assert state is not None + assert state.state == "0" + assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) is None + assert ( + f"Source sensor {source_entity_id} has no unit of measurement." in caplog.text + ) + + async def test_device_id(hass: HomeAssistant) -> None: """Test for source entity device for Utility Meter.""" device_registry = dr.async_get(hass)