From 0404acddf92ab226fea458d43afb3b3e09a9cd9a Mon Sep 17 00:00:00 2001 From: Maciej Bieniek Date: Thu, 10 Jun 2021 20:31:21 +0200 Subject: [PATCH] Add support for state_class (#51512) --- homeassistant/components/brother/const.py | 25 ++++++++++++++++++++++ homeassistant/components/brother/model.py | 1 + homeassistant/components/brother/sensor.py | 3 ++- tests/components/brother/test_sensor.py | 24 ++++++++++++++++++++- 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/brother/const.py b/homeassistant/components/brother/const.py index 52170057fb1..9e2c096ac76 100644 --- a/homeassistant/components/brother/const.py +++ b/homeassistant/components/brother/const.py @@ -3,6 +3,7 @@ from __future__ import annotations from typing import Final +from homeassistant.components.sensor import ATTR_STATE_CLASS, STATE_CLASS_MEASUREMENT from homeassistant.const import ATTR_ICON, PERCENTAGE from .model import SensorDescription @@ -84,143 +85,167 @@ SENSOR_TYPES: Final[dict[str, SensorDescription]] = { ATTR_LABEL: ATTR_STATUS.title(), ATTR_UNIT: None, ATTR_ENABLED: True, + ATTR_STATE_CLASS: None, }, ATTR_PAGE_COUNTER: { ATTR_ICON: "mdi:file-document-outline", ATTR_LABEL: ATTR_PAGE_COUNTER.replace("_", " ").title(), ATTR_UNIT: UNIT_PAGES, ATTR_ENABLED: True, + ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, }, ATTR_BW_COUNTER: { ATTR_ICON: "mdi:file-document-outline", ATTR_LABEL: ATTR_BW_COUNTER.replace("_", " ").title(), ATTR_UNIT: UNIT_PAGES, ATTR_ENABLED: True, + ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, }, ATTR_COLOR_COUNTER: { ATTR_ICON: "mdi:file-document-outline", ATTR_LABEL: ATTR_COLOR_COUNTER.replace("_", " ").title(), ATTR_UNIT: UNIT_PAGES, ATTR_ENABLED: True, + ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, }, ATTR_DUPLEX_COUNTER: { ATTR_ICON: "mdi:file-document-outline", ATTR_LABEL: ATTR_DUPLEX_COUNTER.replace("_", " ").title(), ATTR_UNIT: UNIT_PAGES, ATTR_ENABLED: True, + ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, }, ATTR_DRUM_REMAINING_LIFE: { ATTR_ICON: "mdi:chart-donut", ATTR_LABEL: ATTR_DRUM_REMAINING_LIFE.replace("_", " ").title(), ATTR_UNIT: PERCENTAGE, ATTR_ENABLED: True, + ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, }, ATTR_BLACK_DRUM_REMAINING_LIFE: { ATTR_ICON: "mdi:chart-donut", ATTR_LABEL: ATTR_BLACK_DRUM_REMAINING_LIFE.replace("_", " ").title(), ATTR_UNIT: PERCENTAGE, ATTR_ENABLED: True, + ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, }, ATTR_CYAN_DRUM_REMAINING_LIFE: { ATTR_ICON: "mdi:chart-donut", ATTR_LABEL: ATTR_CYAN_DRUM_REMAINING_LIFE.replace("_", " ").title(), ATTR_UNIT: PERCENTAGE, ATTR_ENABLED: True, + ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, }, ATTR_MAGENTA_DRUM_REMAINING_LIFE: { ATTR_ICON: "mdi:chart-donut", ATTR_LABEL: ATTR_MAGENTA_DRUM_REMAINING_LIFE.replace("_", " ").title(), ATTR_UNIT: PERCENTAGE, ATTR_ENABLED: True, + ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, }, ATTR_YELLOW_DRUM_REMAINING_LIFE: { ATTR_ICON: "mdi:chart-donut", ATTR_LABEL: ATTR_YELLOW_DRUM_REMAINING_LIFE.replace("_", " ").title(), ATTR_UNIT: PERCENTAGE, ATTR_ENABLED: True, + ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, }, ATTR_BELT_UNIT_REMAINING_LIFE: { ATTR_ICON: "mdi:current-ac", ATTR_LABEL: ATTR_BELT_UNIT_REMAINING_LIFE.replace("_", " ").title(), ATTR_UNIT: PERCENTAGE, ATTR_ENABLED: True, + ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, }, ATTR_FUSER_REMAINING_LIFE: { ATTR_ICON: "mdi:water-outline", ATTR_LABEL: ATTR_FUSER_REMAINING_LIFE.replace("_", " ").title(), ATTR_UNIT: PERCENTAGE, ATTR_ENABLED: True, + ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, }, ATTR_LASER_REMAINING_LIFE: { ATTR_ICON: "mdi:spotlight-beam", ATTR_LABEL: ATTR_LASER_REMAINING_LIFE.replace("_", " ").title(), ATTR_UNIT: PERCENTAGE, ATTR_ENABLED: True, + ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, }, ATTR_PF_KIT_1_REMAINING_LIFE: { ATTR_ICON: "mdi:printer-3d", ATTR_LABEL: ATTR_PF_KIT_1_REMAINING_LIFE.replace("_", " ").title(), ATTR_UNIT: PERCENTAGE, ATTR_ENABLED: True, + ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, }, ATTR_PF_KIT_MP_REMAINING_LIFE: { ATTR_ICON: "mdi:printer-3d", ATTR_LABEL: ATTR_PF_KIT_MP_REMAINING_LIFE.replace("_", " ").title(), ATTR_UNIT: PERCENTAGE, ATTR_ENABLED: True, + ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, }, ATTR_BLACK_TONER_REMAINING: { ATTR_ICON: "mdi:printer-3d-nozzle", ATTR_LABEL: ATTR_BLACK_TONER_REMAINING.replace("_", " ").title(), ATTR_UNIT: PERCENTAGE, ATTR_ENABLED: True, + ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, }, ATTR_CYAN_TONER_REMAINING: { ATTR_ICON: "mdi:printer-3d-nozzle", ATTR_LABEL: ATTR_CYAN_TONER_REMAINING.replace("_", " ").title(), ATTR_UNIT: PERCENTAGE, ATTR_ENABLED: True, + ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, }, ATTR_MAGENTA_TONER_REMAINING: { ATTR_ICON: "mdi:printer-3d-nozzle", ATTR_LABEL: ATTR_MAGENTA_TONER_REMAINING.replace("_", " ").title(), ATTR_UNIT: PERCENTAGE, ATTR_ENABLED: True, + ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, }, ATTR_YELLOW_TONER_REMAINING: { ATTR_ICON: "mdi:printer-3d-nozzle", ATTR_LABEL: ATTR_YELLOW_TONER_REMAINING.replace("_", " ").title(), ATTR_UNIT: PERCENTAGE, ATTR_ENABLED: True, + ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, }, ATTR_BLACK_INK_REMAINING: { ATTR_ICON: "mdi:printer-3d-nozzle", ATTR_LABEL: ATTR_BLACK_INK_REMAINING.replace("_", " ").title(), ATTR_UNIT: PERCENTAGE, ATTR_ENABLED: True, + ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, }, ATTR_CYAN_INK_REMAINING: { ATTR_ICON: "mdi:printer-3d-nozzle", ATTR_LABEL: ATTR_CYAN_INK_REMAINING.replace("_", " ").title(), ATTR_UNIT: PERCENTAGE, ATTR_ENABLED: True, + ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, }, ATTR_MAGENTA_INK_REMAINING: { ATTR_ICON: "mdi:printer-3d-nozzle", ATTR_LABEL: ATTR_MAGENTA_INK_REMAINING.replace("_", " ").title(), ATTR_UNIT: PERCENTAGE, ATTR_ENABLED: True, + ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, }, ATTR_YELLOW_INK_REMAINING: { ATTR_ICON: "mdi:printer-3d-nozzle", ATTR_LABEL: ATTR_YELLOW_INK_REMAINING.replace("_", " ").title(), ATTR_UNIT: PERCENTAGE, ATTR_ENABLED: True, + ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, }, ATTR_UPTIME: { ATTR_ICON: None, ATTR_LABEL: ATTR_UPTIME.title(), ATTR_UNIT: None, ATTR_ENABLED: False, + ATTR_STATE_CLASS: None, }, } diff --git a/homeassistant/components/brother/model.py b/homeassistant/components/brother/model.py index 22aa95eda50..d53327ae22a 100644 --- a/homeassistant/components/brother/model.py +++ b/homeassistant/components/brother/model.py @@ -11,3 +11,4 @@ class SensorDescription(TypedDict): label: str unit: str | None enabled: bool + state_class: str | None diff --git a/homeassistant/components/brother/sensor.py b/homeassistant/components/brother/sensor.py index 50c9b8d79ff..773da1d09b1 100644 --- a/homeassistant/components/brother/sensor.py +++ b/homeassistant/components/brother/sensor.py @@ -3,7 +3,7 @@ from __future__ import annotations from typing import Any -from homeassistant.components.sensor import SensorEntity +from homeassistant.components.sensor import ATTR_STATE_CLASS, SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_ICON, DEVICE_CLASS_TIMESTAMP from homeassistant.core import HomeAssistant @@ -66,6 +66,7 @@ class BrotherPrinterSensor(CoordinatorEntity, SensorEntity): self._device_info = device_info self.kind = kind self._attrs: dict[str, Any] = {} + self._attr_state_class = self._description[ATTR_STATE_CLASS] @property def name(self) -> str: diff --git a/tests/components/brother/test_sensor.py b/tests/components/brother/test_sensor.py index 225cf5ce87a..b51577b5f3d 100644 --- a/tests/components/brother/test_sensor.py +++ b/tests/components/brother/test_sensor.py @@ -4,7 +4,11 @@ import json from unittest.mock import Mock, patch from homeassistant.components.brother.const import DOMAIN, UNIT_PAGES -from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN +from homeassistant.components.sensor import ( + ATTR_STATE_CLASS, + DOMAIN as SENSOR_DOMAIN, + STATE_CLASS_MEASUREMENT, +) from homeassistant.const import ( ATTR_DEVICE_CLASS, ATTR_ENTITY_ID, @@ -51,6 +55,7 @@ async def test_sensors(hass): assert state assert state.attributes.get(ATTR_ICON) == "mdi:printer" assert state.state == "waiting" + assert state.attributes.get(ATTR_STATE_CLASS) is None entry = registry.async_get("sensor.hl_l2340dw_status") assert entry @@ -61,6 +66,7 @@ async def test_sensors(hass): assert state.attributes.get(ATTR_ICON) == "mdi:printer-3d-nozzle" assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE assert state.state == "75" + assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT entry = registry.async_get("sensor.hl_l2340dw_black_toner_remaining") assert entry @@ -71,6 +77,7 @@ async def test_sensors(hass): assert state.attributes.get(ATTR_ICON) == "mdi:printer-3d-nozzle" assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE assert state.state == "10" + assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT entry = registry.async_get("sensor.hl_l2340dw_cyan_toner_remaining") assert entry @@ -81,6 +88,7 @@ async def test_sensors(hass): assert state.attributes.get(ATTR_ICON) == "mdi:printer-3d-nozzle" assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE assert state.state == "8" + assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT entry = registry.async_get("sensor.hl_l2340dw_magenta_toner_remaining") assert entry @@ -91,6 +99,7 @@ async def test_sensors(hass): assert state.attributes.get(ATTR_ICON) == "mdi:printer-3d-nozzle" assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE assert state.state == "2" + assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT entry = registry.async_get("sensor.hl_l2340dw_yellow_toner_remaining") assert entry @@ -103,6 +112,7 @@ async def test_sensors(hass): assert state.attributes.get(ATTR_COUNTER) == 986 assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE assert state.state == "92" + assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT entry = registry.async_get("sensor.hl_l2340dw_drum_remaining_life") assert entry @@ -115,6 +125,7 @@ async def test_sensors(hass): assert state.attributes.get(ATTR_COUNTER) == 1611 assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE assert state.state == "92" + assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT entry = registry.async_get("sensor.hl_l2340dw_black_drum_remaining_life") assert entry @@ -127,6 +138,7 @@ async def test_sensors(hass): assert state.attributes.get(ATTR_COUNTER) == 1611 assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE assert state.state == "92" + assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT entry = registry.async_get("sensor.hl_l2340dw_cyan_drum_remaining_life") assert entry @@ -139,6 +151,7 @@ async def test_sensors(hass): assert state.attributes.get(ATTR_COUNTER) == 1611 assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE assert state.state == "92" + assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT entry = registry.async_get("sensor.hl_l2340dw_magenta_drum_remaining_life") assert entry @@ -151,6 +164,7 @@ async def test_sensors(hass): assert state.attributes.get(ATTR_COUNTER) == 1611 assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE assert state.state == "92" + assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT entry = registry.async_get("sensor.hl_l2340dw_yellow_drum_remaining_life") assert entry @@ -161,6 +175,7 @@ async def test_sensors(hass): assert state.attributes.get(ATTR_ICON) == "mdi:water-outline" assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE assert state.state == "97" + assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT entry = registry.async_get("sensor.hl_l2340dw_fuser_remaining_life") assert entry @@ -171,6 +186,7 @@ async def test_sensors(hass): assert state.attributes.get(ATTR_ICON) == "mdi:current-ac" assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE assert state.state == "97" + assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT entry = registry.async_get("sensor.hl_l2340dw_belt_unit_remaining_life") assert entry @@ -181,6 +197,7 @@ async def test_sensors(hass): assert state.attributes.get(ATTR_ICON) == "mdi:printer-3d" assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PERCENTAGE assert state.state == "98" + assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT entry = registry.async_get("sensor.hl_l2340dw_pf_kit_1_remaining_life") assert entry @@ -191,6 +208,7 @@ async def test_sensors(hass): assert state.attributes.get(ATTR_ICON) == "mdi:file-document-outline" assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PAGES assert state.state == "986" + assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT entry = registry.async_get("sensor.hl_l2340dw_page_counter") assert entry @@ -201,6 +219,7 @@ async def test_sensors(hass): assert state.attributes.get(ATTR_ICON) == "mdi:file-document-outline" assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PAGES assert state.state == "538" + assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT entry = registry.async_get("sensor.hl_l2340dw_duplex_unit_pages_counter") assert entry @@ -211,6 +230,7 @@ async def test_sensors(hass): assert state.attributes.get(ATTR_ICON) == "mdi:file-document-outline" assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PAGES assert state.state == "709" + assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT entry = registry.async_get("sensor.hl_l2340dw_b_w_counter") assert entry @@ -221,6 +241,7 @@ async def test_sensors(hass): assert state.attributes.get(ATTR_ICON) == "mdi:file-document-outline" assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == UNIT_PAGES assert state.state == "902" + assert state.attributes.get(ATTR_STATE_CLASS) == STATE_CLASS_MEASUREMENT entry = registry.async_get("sensor.hl_l2340dw_color_counter") assert entry @@ -232,6 +253,7 @@ async def test_sensors(hass): assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) is None assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_TIMESTAMP assert state.state == "2019-09-24T12:14:56+00:00" + assert state.attributes.get(ATTR_STATE_CLASS) is None entry = registry.async_get("sensor.hl_l2340dw_uptime") assert entry