Only set attributes based on the configured type for min_max sensors (#70142)

This commit is contained in:
J. Nick Koston 2022-04-17 19:53:49 -10:00 committed by GitHub
parent b4ef150339
commit 40eb1554d9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 63 deletions

View file

@ -31,24 +31,11 @@ ATTR_MIN_VALUE = "min_value"
ATTR_MIN_ENTITY_ID = "min_entity_id"
ATTR_MAX_VALUE = "max_value"
ATTR_MAX_ENTITY_ID = "max_entity_id"
ATTR_COUNT_SENSORS = "count_sensors"
ATTR_MEAN = "mean"
ATTR_MEDIAN = "median"
ATTR_LAST = "last"
ATTR_LAST_ENTITY_ID = "last_entity_id"
ATTR_TO_PROPERTY = [
ATTR_COUNT_SENSORS,
ATTR_MAX_VALUE,
ATTR_MAX_ENTITY_ID,
ATTR_MEAN,
ATTR_MEDIAN,
ATTR_MIN_VALUE,
ATTR_MIN_ENTITY_ID,
ATTR_LAST,
ATTR_LAST_ENTITY_ID,
]
ICON = "mdi:calculator"
SENSOR_TYPES = {
@ -58,6 +45,7 @@ SENSOR_TYPES = {
ATTR_MEDIAN: "median",
ATTR_LAST: "last",
}
SENSOR_TYPE_TO_ATTR = {v: k for k, v in SENSOR_TYPES.items()}
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{
@ -179,7 +167,8 @@ class MinMaxSensor(SensorEntity):
if name:
self._name = name
else:
self._name = f"{next(v for k, v in SENSOR_TYPES.items() if self._sensor_type == v)} sensor".capitalize()
self._name = f"{sensor_type} sensor".capitalize()
self._sensor_attr = SENSOR_TYPE_TO_ATTR[self._sensor_type]
self._unit_of_measurement = None
self._unit_of_measurement_mismatch = False
self.min_value = self.max_value = self.mean = self.last = self.median = None
@ -213,9 +202,7 @@ class MinMaxSensor(SensorEntity):
"""Return the state of the sensor."""
if self._unit_of_measurement_mismatch:
return None
return getattr(
self, next(k for k, v in SENSOR_TYPES.items() if self._sensor_type == v)
)
return getattr(self, self._sensor_attr)
@property
def native_unit_of_measurement(self):
@ -232,11 +219,13 @@ class MinMaxSensor(SensorEntity):
@property
def extra_state_attributes(self):
"""Return the state attributes of the sensor."""
return {
attr: getattr(self, attr)
for attr in ATTR_TO_PROPERTY
if getattr(self, attr) is not None
}
if self._sensor_type == "min":
return {ATTR_MIN_ENTITY_ID: self.min_entity_id}
if self._sensor_type == "max":
return {ATTR_MAX_ENTITY_ID: self.max_entity_id}
if self._sensor_type == "last":
return {ATTR_LAST_ENTITY_ID: self.last_entity_id}
return None
@property
def icon(self):

View file

@ -132,4 +132,3 @@ async def test_options(hass: HomeAssistant, platform) -> None:
# Check the state of the entity has changed as expected
state = hass.states.get(f"{platform}.my_min_max")
assert state.state == "21.1"
assert state.attributes["count_sensors"] == 3

View file

@ -44,7 +44,6 @@ async def test_setup_and_remove_config_entry(
# Check the platform is setup correctly
state = hass.states.get(min_max_entity_id)
assert state.state == "20.0"
assert state.attributes["count_sensors"] == 2
# Remove the config entry
assert await hass.config_entries.async_remove(config_entry.entry_id)

View file

@ -27,6 +27,31 @@ MEAN_4_DIGITS = round(sum(VALUES) / COUNT, 4)
MEDIAN = round(statistics.median(VALUES), 2)
async def test_default_name_sensor(hass):
"""Test the min sensor with a default name."""
config = {
"sensor": {
"platform": "min_max",
"type": "min",
"entity_ids": ["sensor.test_1", "sensor.test_2", "sensor.test_3"],
}
}
assert await async_setup_component(hass, "sensor", config)
await hass.async_block_till_done()
entity_ids = config["sensor"]["entity_ids"]
for entity_id, value in dict(zip(entity_ids, VALUES)).items():
hass.states.async_set(entity_id, value)
await hass.async_block_till_done()
state = hass.states.get("sensor.min_sensor")
assert str(float(MIN_VALUE)) == state.state
assert entity_ids[2] == state.attributes.get("min_entity_id")
async def test_min_sensor(hass):
"""Test the min sensor."""
config = {
@ -51,10 +76,6 @@ async def test_min_sensor(hass):
assert str(float(MIN_VALUE)) == state.state
assert entity_ids[2] == state.attributes.get("min_entity_id")
assert state.attributes.get("max_value") == MAX_VALUE
assert entity_ids[1] == state.attributes.get("max_entity_id")
assert state.attributes.get("mean") == MEAN
assert state.attributes.get("median") == MEDIAN
async def test_max_sensor(hass):
@ -80,11 +101,7 @@ async def test_max_sensor(hass):
state = hass.states.get("sensor.test_max")
assert str(float(MAX_VALUE)) == state.state
assert entity_ids[2] == state.attributes.get("min_entity_id")
assert state.attributes.get("min_value") == MIN_VALUE
assert entity_ids[1] == state.attributes.get("max_entity_id")
assert state.attributes.get("mean") == MEAN
assert state.attributes.get("median") == MEDIAN
async def test_mean_sensor(hass):
@ -110,11 +127,6 @@ async def test_mean_sensor(hass):
state = hass.states.get("sensor.test_mean")
assert str(float(MEAN)) == state.state
assert state.attributes.get("min_value") == MIN_VALUE
assert entity_ids[2] == state.attributes.get("min_entity_id")
assert state.attributes.get("max_value") == MAX_VALUE
assert entity_ids[1] == state.attributes.get("max_entity_id")
assert state.attributes.get("median") == MEDIAN
async def test_mean_1_digit_sensor(hass):
@ -141,11 +153,6 @@ async def test_mean_1_digit_sensor(hass):
state = hass.states.get("sensor.test_mean")
assert str(float(MEAN_1_DIGIT)) == state.state
assert state.attributes.get("min_value") == MIN_VALUE
assert entity_ids[2] == state.attributes.get("min_entity_id")
assert state.attributes.get("max_value") == MAX_VALUE
assert entity_ids[1] == state.attributes.get("max_entity_id")
assert state.attributes.get("median") == MEDIAN
async def test_mean_4_digit_sensor(hass):
@ -172,11 +179,6 @@ async def test_mean_4_digit_sensor(hass):
state = hass.states.get("sensor.test_mean")
assert str(float(MEAN_4_DIGITS)) == state.state
assert state.attributes.get("min_value") == MIN_VALUE
assert entity_ids[2] == state.attributes.get("min_entity_id")
assert state.attributes.get("max_value") == MAX_VALUE
assert entity_ids[1] == state.attributes.get("max_entity_id")
assert state.attributes.get("median") == MEDIAN
async def test_median_sensor(hass):
@ -202,11 +204,6 @@ async def test_median_sensor(hass):
state = hass.states.get("sensor.test_median")
assert str(float(MEDIAN)) == state.state
assert state.attributes.get("min_value") == MIN_VALUE
assert entity_ids[2] == state.attributes.get("min_entity_id")
assert state.attributes.get("max_value") == MAX_VALUE
assert entity_ids[1] == state.attributes.get("max_entity_id")
assert state.attributes.get("mean") == MEAN
async def test_not_enough_sensor_value(hass):
@ -241,20 +238,14 @@ async def test_not_enough_sensor_value(hass):
state = hass.states.get("sensor.test_max")
assert STATE_UNKNOWN != state.state
assert entity_ids[1] == state.attributes.get("min_entity_id")
assert VALUES[1] == state.attributes.get("min_value")
assert entity_ids[1] == state.attributes.get("max_entity_id")
assert VALUES[1] == state.attributes.get("max_value")
hass.states.async_set(entity_ids[2], STATE_UNKNOWN)
await hass.async_block_till_done()
state = hass.states.get("sensor.test_max")
assert STATE_UNKNOWN != state.state
assert entity_ids[1] == state.attributes.get("min_entity_id")
assert VALUES[1] == state.attributes.get("min_value")
assert entity_ids[1] == state.attributes.get("max_entity_id")
assert VALUES[1] == state.attributes.get("max_value")
hass.states.async_set(entity_ids[1], STATE_UNAVAILABLE)
await hass.async_block_till_done()
@ -337,11 +328,6 @@ async def test_last_sensor(hass):
assert str(float(value)) == state.state
assert entity_id == state.attributes.get("last_entity_id")
assert state.attributes.get("min_value") == MIN_VALUE
assert state.attributes.get("max_value") == MAX_VALUE
assert state.attributes.get("mean") == MEAN
assert state.attributes.get("median") == MEDIAN
async def test_reload(hass):
"""Verify we can reload filter sensors."""