Add state_class support to Rest (#58026)

pull/58484/head
Chris Browet 2021-10-22 22:48:13 +02:00 committed by GitHub
parent ee087c7a05
commit 1867d24b18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 52 additions and 21 deletions

View File

@ -85,14 +85,14 @@ class RestBinarySensor(RestEntity, BinarySensorEntity):
resource_template,
):
"""Initialize a REST binary sensor."""
super().__init__(
coordinator, rest, name, device_class, resource_template, force_update
)
super().__init__(coordinator, rest, name, resource_template, force_update)
self._state = False
self._previous_data = None
self._value_template = value_template
self._is_on = None
self._attr_device_class = device_class
@property
def is_on(self):
"""Return true if the binary sensor is on."""

View File

@ -18,7 +18,6 @@ class RestEntity(Entity):
coordinator: DataUpdateCoordinator[Any],
rest: RestData,
name,
device_class,
resource_template,
force_update,
) -> None:
@ -26,7 +25,6 @@ class RestEntity(Entity):
self.coordinator = coordinator
self.rest = rest
self._name = name
self._device_class = device_class
self._resource_template = resource_template
self._force_update = force_update
super().__init__()
@ -36,11 +34,6 @@ class RestEntity(Entity):
"""Return the name of the sensor."""
return self._name
@property
def device_class(self):
"""Return the class of this sensor."""
return self._device_class
@property
def force_update(self):
"""Force update."""

View File

@ -9,7 +9,9 @@ from homeassistant.components.binary_sensor import (
from homeassistant.components.sensor import (
DEVICE_CLASSES_SCHEMA as SENSOR_DEVICE_CLASSES_SCHEMA,
DOMAIN as SENSOR_DOMAIN,
STATE_CLASSES_SCHEMA,
)
from homeassistant.components.sensor.const import CONF_STATE_CLASS
from homeassistant.const import (
CONF_AUTHENTICATION,
CONF_DEVICE_CLASS,
@ -66,6 +68,7 @@ SENSOR_SCHEMA = {
vol.Optional(CONF_NAME, default=DEFAULT_SENSOR_NAME): cv.string,
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
vol.Optional(CONF_DEVICE_CLASS): SENSOR_DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_STATE_CLASS): STATE_CLASSES_SCHEMA,
vol.Optional(CONF_JSON_ATTRS, default=[]): cv.ensure_list_csv,
vol.Optional(CONF_JSON_ATTRS_PATH): cv.string,
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,

View File

@ -8,6 +8,7 @@ import voluptuous as vol
import xmltodict
from homeassistant.components.sensor import (
CONF_STATE_CLASS,
DOMAIN as SENSOR_DOMAIN,
PLATFORM_SCHEMA,
SensorEntity,
@ -60,6 +61,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
name = conf.get(CONF_NAME)
unit = conf.get(CONF_UNIT_OF_MEASUREMENT)
device_class = conf.get(CONF_DEVICE_CLASS)
state_class = conf.get(CONF_STATE_CLASS)
json_attrs = conf.get(CONF_JSON_ATTRS)
json_attrs_path = conf.get(CONF_JSON_ATTRS_PATH)
value_template = conf.get(CONF_VALUE_TEMPLATE)
@ -77,6 +79,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
name,
unit,
device_class,
state_class,
value_template,
json_attrs,
force_update,
@ -97,6 +100,7 @@ class RestSensor(RestEntity, SensorEntity):
name,
unit_of_measurement,
device_class,
state_class,
value_template,
json_attrs,
force_update,
@ -104,9 +108,7 @@ class RestSensor(RestEntity, SensorEntity):
json_attrs_path,
):
"""Initialize the REST sensor."""
super().__init__(
coordinator, rest, name, device_class, resource_template, force_update
)
super().__init__(coordinator, rest, name, resource_template, force_update)
self._state = None
self._unit_of_measurement = unit_of_measurement
self._value_template = value_template
@ -114,10 +116,9 @@ class RestSensor(RestEntity, SensorEntity):
self._attributes = None
self._json_attrs_path = json_attrs_path
@property
def native_unit_of_measurement(self):
"""Return the unit the value is expressed in."""
return self._unit_of_measurement
self._attr_native_unit_of_measurement = self._unit_of_measurement
self._attr_device_class = device_class
self._attr_state_class = state_class
@property
def native_value(self):

View File

@ -6,8 +6,13 @@ import aiohttp
import async_timeout
import voluptuous as vol
from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchEntity
from homeassistant.components.switch import (
DEVICE_CLASSES_SCHEMA,
PLATFORM_SCHEMA,
SwitchEntity,
)
from homeassistant.const import (
CONF_DEVICE_CLASS,
CONF_HEADERS,
CONF_METHOD,
CONF_NAME,
@ -51,6 +56,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
vol.Lower, vol.In(SUPPORT_REST_METHODS)
),
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA,
vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
vol.Inclusive(CONF_USERNAME, "authentication"): cv.string,
vol.Inclusive(CONF_PASSWORD, "authentication"): cv.string,
@ -68,6 +74,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
headers = config.get(CONF_HEADERS)
params = config.get(CONF_PARAMS)
name = config.get(CONF_NAME)
device_class = config.get(CONF_DEVICE_CLASS)
username = config.get(CONF_USERNAME)
password = config.get(CONF_PASSWORD)
resource = config.get(CONF_RESOURCE)
@ -89,6 +96,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
try:
switch = RestSwitch(
name,
device_class,
resource,
state_resource,
method,
@ -122,6 +130,7 @@ class RestSwitch(SwitchEntity):
def __init__(
self,
name,
device_class,
resource,
state_resource,
method,
@ -149,6 +158,8 @@ class RestSwitch(SwitchEntity):
self._timeout = timeout
self._verify_ssl = verify_ssl
self._attr_device_class = device_class
@property
def name(self):
"""Return the name of the switch."""

View File

@ -10,6 +10,7 @@ import respx
from homeassistant import config as hass_config
import homeassistant.components.binary_sensor as binary_sensor
from homeassistant.const import (
ATTR_DEVICE_CLASS,
ATTR_ENTITY_ID,
CONTENT_TYPE_JSON,
SERVICE_RELOAD,
@ -164,6 +165,7 @@ async def test_setup_get(hass):
"username": "my username",
"password": "my password",
"headers": {"Accept": CONTENT_TYPE_JSON},
"device_class": binary_sensor.DEVICE_CLASS_PLUG,
}
},
)
@ -171,6 +173,10 @@ async def test_setup_get(hass):
await hass.async_block_till_done()
assert len(hass.states.async_all("binary_sensor")) == 1
state = hass.states.get("binary_sensor.foo")
assert state.state == STATE_OFF
assert state.attributes[ATTR_DEVICE_CLASS] == binary_sensor.DEVICE_CLASS_PLUG
@respx.mock
async def test_setup_get_digest_auth(hass):

View File

@ -10,12 +10,15 @@ from homeassistant import config as hass_config
from homeassistant.components.homeassistant import SERVICE_UPDATE_ENTITY
import homeassistant.components.sensor as sensor
from homeassistant.const import (
ATTR_DEVICE_CLASS,
ATTR_ENTITY_ID,
ATTR_UNIT_OF_MEASUREMENT,
CONTENT_TYPE_JSON,
DATA_MEGABYTES,
DEVICE_CLASS_TEMPERATURE,
SERVICE_RELOAD,
STATE_UNKNOWN,
TEMP_CELSIUS,
)
from homeassistant.setup import async_setup_component
@ -177,13 +180,15 @@ async def test_setup_get(hass):
"method": "GET",
"value_template": "{{ value_json.key }}",
"name": "foo",
"unit_of_measurement": DATA_MEGABYTES,
"unit_of_measurement": TEMP_CELSIUS,
"verify_ssl": "true",
"timeout": 30,
"authentication": "basic",
"username": "my username",
"password": "my password",
"headers": {"Accept": CONTENT_TYPE_JSON},
"device_class": DEVICE_CLASS_TEMPERATURE,
"state_class": sensor.STATE_CLASS_MEASUREMENT,
}
},
)
@ -200,7 +205,11 @@ async def test_setup_get(hass):
blocking=True,
)
await hass.async_block_till_done()
assert hass.states.get("sensor.foo").state == ""
state = hass.states.get("sensor.foo")
assert state.state == ""
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == TEMP_CELSIUS
assert state.attributes[ATTR_DEVICE_CLASS] == DEVICE_CLASS_TEMPERATURE
assert state.attributes[sensor.ATTR_STATE_CLASS] == sensor.STATE_CLASS_MEASUREMENT
@respx.mock

View File

@ -6,7 +6,7 @@ import aiohttp
from homeassistant.components.rest import DOMAIN
import homeassistant.components.rest.switch as rest
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
from homeassistant.components.switch import DEVICE_CLASS_SWITCH, DOMAIN as SWITCH_DOMAIN
from homeassistant.const import (
CONF_HEADERS,
CONF_NAME,
@ -23,6 +23,7 @@ from tests.common import assert_setup_component
"""Tests for setting up the REST switch platform."""
NAME = "foo"
DEVICE_CLASS = DEVICE_CLASS_SWITCH
METHOD = "post"
RESOURCE = "http://localhost/"
STATE_RESOURCE = RESOURCE
@ -158,6 +159,7 @@ def _setup_test_switch(hass):
body_off = Template("off", hass)
switch = rest.RestSwitch(
NAME,
DEVICE_CLASS,
RESOURCE,
STATE_RESOURCE,
METHOD,
@ -180,6 +182,12 @@ def test_name(hass):
assert switch.name == NAME
def test_device_class(hass):
"""Test the name."""
switch, body_on, body_off = _setup_test_switch(hass)
assert switch.device_class == DEVICE_CLASS
def test_is_on_before_update(hass):
"""Test is_on in initial state."""
switch, body_on, body_off = _setup_test_switch(hass)