Add support for Sensirion SHT31 temperature/humidity sensor (#12952)
This commit is contained in:
parent
37cd63ea5a
commit
3180c8b0fb
3 changed files with 159 additions and 0 deletions
152
homeassistant/components/sensor/sht31.py
Normal file
152
homeassistant/components/sensor/sht31.py
Normal file
|
@ -0,0 +1,152 @@
|
|||
"""
|
||||
Support for Sensirion SHT31 temperature and humidity sensor.
|
||||
|
||||
For more details about this platform, please refer to the documentation at
|
||||
https://home-assistant.io/components/sensor.sht31/
|
||||
"""
|
||||
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
import math
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
||||
from homeassistant.const import (
|
||||
TEMP_CELSIUS, CONF_NAME, CONF_MONITORED_CONDITIONS)
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.helpers.temperature import display_temp
|
||||
from homeassistant.const import PRECISION_TENTHS
|
||||
from homeassistant.util import Throttle
|
||||
|
||||
|
||||
REQUIREMENTS = ['Adafruit-GPIO==1.0.3',
|
||||
'Adafruit-SHT31==1.0.2']
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CONF_I2C_ADDRESS = 'i2c_address'
|
||||
|
||||
DEFAULT_NAME = 'SHT31'
|
||||
DEFAULT_I2C_ADDRESS = 0x44
|
||||
|
||||
SENSOR_TEMPERATURE = 'temperature'
|
||||
SENSOR_HUMIDITY = 'humidity'
|
||||
SENSOR_TYPES = (SENSOR_TEMPERATURE, SENSOR_HUMIDITY)
|
||||
|
||||
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=10)
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
vol.Optional(CONF_I2C_ADDRESS, default=DEFAULT_I2C_ADDRESS):
|
||||
vol.All(vol.Coerce(int), vol.Range(min=0x44, max=0x45)),
|
||||
vol.Optional(CONF_MONITORED_CONDITIONS, default=list(SENSOR_TYPES)):
|
||||
vol.All(cv.ensure_list, [vol.In(SENSOR_TYPES)]),
|
||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||
})
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the sensor platform."""
|
||||
from Adafruit_SHT31 import SHT31
|
||||
|
||||
i2c_address = config.get(CONF_I2C_ADDRESS)
|
||||
sensor = SHT31(address=i2c_address)
|
||||
|
||||
try:
|
||||
if sensor.read_status() is None:
|
||||
raise ValueError("CRC error while reading SHT31 status")
|
||||
except (OSError, ValueError):
|
||||
raise HomeAssistantError("SHT31 sensor not detected at address %s " %
|
||||
hex(i2c_address))
|
||||
sensor_client = SHTClient(sensor)
|
||||
|
||||
sensor_classes = {
|
||||
SENSOR_TEMPERATURE: SHTSensorTemperature,
|
||||
SENSOR_HUMIDITY: SHTSensorHumidity
|
||||
}
|
||||
|
||||
devs = []
|
||||
for sensor_type, sensor_class in sensor_classes.items():
|
||||
name = "{} {}".format(config.get(CONF_NAME), sensor_type.capitalize())
|
||||
devs.append(sensor_class(sensor_client, name))
|
||||
|
||||
add_devices(devs)
|
||||
|
||||
|
||||
class SHTClient(object):
|
||||
"""Get the latest data from the SHT sensor."""
|
||||
|
||||
def __init__(self, adafruit_sht):
|
||||
"""Initialize the sensor."""
|
||||
self.adafruit_sht = adafruit_sht
|
||||
self.temperature = None
|
||||
self.humidity = None
|
||||
|
||||
@Throttle(MIN_TIME_BETWEEN_UPDATES)
|
||||
def update(self):
|
||||
"""Get the latest data from the SHT sensor."""
|
||||
temperature, humidity = self.adafruit_sht.read_temperature_humidity()
|
||||
if math.isnan(temperature) or math.isnan(humidity):
|
||||
_LOGGER.warning("Bad sample from sensor SHT31")
|
||||
return
|
||||
self.temperature = temperature
|
||||
self.humidity = humidity
|
||||
|
||||
|
||||
class SHTSensor(Entity):
|
||||
"""An abstract SHTSensor, can be either temperature or humidity."""
|
||||
|
||||
def __init__(self, sensor, name):
|
||||
"""Initialize the sensor."""
|
||||
self._sensor = sensor
|
||||
self._name = name
|
||||
self._state = None
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the sensor."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the state of the sensor."""
|
||||
return self._state
|
||||
|
||||
def update(self):
|
||||
"""Fetch temperature and humidity from the sensor."""
|
||||
self._sensor.update()
|
||||
|
||||
|
||||
class SHTSensorTemperature(SHTSensor):
|
||||
"""Representation of a temperature sensor."""
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
"""Return the unit of measurement."""
|
||||
return self.hass.config.units.temperature_unit
|
||||
|
||||
def update(self):
|
||||
"""Fetch temperature from the sensor."""
|
||||
super().update()
|
||||
temp_celsius = self._sensor.temperature
|
||||
if temp_celsius is not None:
|
||||
self._state = display_temp(self.hass, temp_celsius,
|
||||
TEMP_CELSIUS, PRECISION_TENTHS)
|
||||
|
||||
|
||||
class SHTSensorHumidity(SHTSensor):
|
||||
"""Representation of a humidity sensor."""
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
"""Return the unit of measurement."""
|
||||
return '%'
|
||||
|
||||
def update(self):
|
||||
"""Fetch humidity from the sensor."""
|
||||
super().update()
|
||||
humidity = self._sensor.humidity
|
||||
if humidity is not None:
|
||||
self._state = round(humidity)
|
Loading…
Add table
Add a link
Reference in a new issue