Use EntityDescription - mhz19 (#55187)

* Use EntityDescription - mhz19

* Fix tests
This commit is contained in:
Marc Mueller 2021-08-25 13:52:59 +02:00 committed by GitHub
parent 504d23ac72
commit 7f203069a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 33 deletions

View File

@ -1,11 +1,17 @@
"""Support for CO2 sensor connected to a serial port.""" """Support for CO2 sensor connected to a serial port."""
from __future__ import annotations
from datetime import timedelta from datetime import timedelta
import logging import logging
from pmsensor import co2sensor from pmsensor import co2sensor
import voluptuous as vol import voluptuous as vol
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity from homeassistant.components.sensor import (
PLATFORM_SCHEMA,
SensorEntity,
SensorEntityDescription,
)
from homeassistant.const import ( from homeassistant.const import (
ATTR_TEMPERATURE, ATTR_TEMPERATURE,
CONCENTRATION_PARTS_PER_MILLION, CONCENTRATION_PARTS_PER_MILLION,
@ -29,16 +35,27 @@ ATTR_CO2_CONCENTRATION = "co2_concentration"
SENSOR_TEMPERATURE = "temperature" SENSOR_TEMPERATURE = "temperature"
SENSOR_CO2 = "co2" SENSOR_CO2 = "co2"
SENSOR_TYPES = { SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
SENSOR_TEMPERATURE: ["Temperature", TEMP_CELSIUS, DEVICE_CLASS_TEMPERATURE], SensorEntityDescription(
SENSOR_CO2: ["CO2", CONCENTRATION_PARTS_PER_MILLION, DEVICE_CLASS_CO2], key=SENSOR_TEMPERATURE,
} name="Temperature",
native_unit_of_measurement=TEMP_CELSIUS,
device_class=DEVICE_CLASS_TEMPERATURE,
),
SensorEntityDescription(
key=SENSOR_CO2,
name="CO2",
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
device_class=DEVICE_CLASS_CO2,
),
)
SENSOR_KEYS: list[str] = [desc.key for desc in SENSOR_TYPES]
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{ {
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Required(CONF_SERIAL_DEVICE): cv.string, vol.Required(CONF_SERIAL_DEVICE): cv.string,
vol.Optional(CONF_MONITORED_CONDITIONS, default=[SENSOR_CO2]): vol.All( vol.Optional(CONF_MONITORED_CONDITIONS, default=[SENSOR_CO2]): vol.All(
cv.ensure_list, [vol.In(SENSOR_TYPES)] cv.ensure_list, [vol.In(SENSOR_KEYS)]
), ),
} }
) )
@ -58,43 +75,36 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
return False return False
data = MHZClient(co2sensor, config.get(CONF_SERIAL_DEVICE)) data = MHZClient(co2sensor, config.get(CONF_SERIAL_DEVICE))
dev = [] name = config[CONF_NAME]
name = config.get(CONF_NAME)
for variable in config[CONF_MONITORED_CONDITIONS]: monitored_conditions = config[CONF_MONITORED_CONDITIONS]
dev.append(MHZ19Sensor(data, variable, name)) entities = [
MHZ19Sensor(data, name, description)
for description in SENSOR_TYPES
if description.key in monitored_conditions
]
add_entities(dev, True) add_entities(entities, True)
return True
class MHZ19Sensor(SensorEntity): class MHZ19Sensor(SensorEntity):
"""Representation of an CO2 sensor.""" """Representation of an CO2 sensor."""
def __init__(self, mhz_client, sensor_type, name): def __init__(self, mhz_client, name, description: SensorEntityDescription):
"""Initialize a new PM sensor.""" """Initialize a new PM sensor."""
self.entity_description = description
self._mhz_client = mhz_client self._mhz_client = mhz_client
self._sensor_type = sensor_type
self._name = name
self._unit_of_measurement = SENSOR_TYPES[sensor_type][1]
self._ppm = None self._ppm = None
self._temperature = None self._temperature = None
self._attr_device_class = SENSOR_TYPES[sensor_type][2]
@property self._attr_name = f"{name}: {description.name}"
def name(self):
"""Return the name of the sensor."""
return f"{self._name}: {SENSOR_TYPES[self._sensor_type][0]}"
@property @property
def native_value(self): def native_value(self):
"""Return the state of the sensor.""" """Return the state of the sensor."""
return self._ppm if self._sensor_type == SENSOR_CO2 else self._temperature if self.entity_description.key == SENSOR_CO2:
return self._ppm
@property return self._temperature
def native_unit_of_measurement(self):
"""Return the unit of measurement of this entity, if any."""
return self._unit_of_measurement
def update(self): def update(self):
"""Read from sensor and update the state.""" """Read from sensor and update the state."""
@ -107,9 +117,10 @@ class MHZ19Sensor(SensorEntity):
def extra_state_attributes(self): def extra_state_attributes(self):
"""Return the state attributes.""" """Return the state attributes."""
result = {} result = {}
if self._sensor_type == SENSOR_TEMPERATURE and self._ppm is not None: sensor_type = self.entity_description.key
if sensor_type == SENSOR_TEMPERATURE and self._ppm is not None:
result[ATTR_CO2_CONCENTRATION] = self._ppm result[ATTR_CO2_CONCENTRATION] = self._ppm
if self._sensor_type == SENSOR_CO2 and self._temperature is not None: elif sensor_type == SENSOR_CO2 and self._temperature is not None:
result[ATTR_TEMPERATURE] = self._temperature result[ATTR_TEMPERATURE] = self._temperature
return result return result

View File

@ -43,10 +43,11 @@ async def test_setup_connected(hass):
): ):
read_mh_z19_with_temperature.return_value = None read_mh_z19_with_temperature.return_value = None
mock_add = Mock() mock_add = Mock()
assert mhz19.setup_platform( mhz19.setup_platform(
hass, hass,
{ {
"platform": "mhz19", "platform": "mhz19",
"name": "name",
"monitored_conditions": ["co2", "temperature"], "monitored_conditions": ["co2", "temperature"],
mhz19.CONF_SERIAL_DEVICE: "test.serial", mhz19.CONF_SERIAL_DEVICE: "test.serial",
}, },
@ -86,7 +87,7 @@ async def aiohttp_client_update_good_read(mock_function):
async def test_co2_sensor(mock_function, hass): async def test_co2_sensor(mock_function, hass):
"""Test CO2 sensor.""" """Test CO2 sensor."""
client = mhz19.MHZClient(co2sensor, "test.serial") client = mhz19.MHZClient(co2sensor, "test.serial")
sensor = mhz19.MHZ19Sensor(client, mhz19.SENSOR_CO2, "name") sensor = mhz19.MHZ19Sensor(client, "name", mhz19.SENSOR_TYPES[1])
sensor.hass = hass sensor.hass = hass
sensor.update() sensor.update()
@ -101,7 +102,7 @@ async def test_co2_sensor(mock_function, hass):
async def test_temperature_sensor(mock_function, hass): async def test_temperature_sensor(mock_function, hass):
"""Test temperature sensor.""" """Test temperature sensor."""
client = mhz19.MHZClient(co2sensor, "test.serial") client = mhz19.MHZClient(co2sensor, "test.serial")
sensor = mhz19.MHZ19Sensor(client, mhz19.SENSOR_TEMPERATURE, "name") sensor = mhz19.MHZ19Sensor(client, "name", mhz19.SENSOR_TYPES[0])
sensor.hass = hass sensor.hass = hass
sensor.update() sensor.update()
@ -117,7 +118,7 @@ async def test_temperature_sensor_f(mock_function, hass):
"""Test temperature sensor.""" """Test temperature sensor."""
with patch.object(hass.config.units, "temperature_unit", TEMP_FAHRENHEIT): with patch.object(hass.config.units, "temperature_unit", TEMP_FAHRENHEIT):
client = mhz19.MHZClient(co2sensor, "test.serial") client = mhz19.MHZClient(co2sensor, "test.serial")
sensor = mhz19.MHZ19Sensor(client, mhz19.SENSOR_TEMPERATURE, "name") sensor = mhz19.MHZ19Sensor(client, "name", mhz19.SENSOR_TYPES[0])
sensor.hass = hass sensor.hass = hass
sensor.update() sensor.update()