diff --git a/.coveragerc b/.coveragerc index 279dc114a21..41794b810f4 100644 --- a/.coveragerc +++ b/.coveragerc @@ -368,6 +368,7 @@ omit = homeassistant/components/sensor/eddystone_temperature.py homeassistant/components/sensor/eliqonline.py homeassistant/components/sensor/emoncms.py + homeassistant/components/sensor/envirophat.py homeassistant/components/sensor/fastdotcom.py homeassistant/components/sensor/fedex.py homeassistant/components/sensor/fido.py diff --git a/homeassistant/components/sensor/envirophat.py b/homeassistant/components/sensor/envirophat.py new file mode 100644 index 00000000000..0c4bb42cf8f --- /dev/null +++ b/homeassistant/components/sensor/envirophat.py @@ -0,0 +1,194 @@ +""" +Support for Enviro pHAT sensors. + +For more details about this component, please refer to the documentation at +https://home-assistant.io/components/sensor.envirophat +""" +import logging +from datetime import timedelta + +import voluptuous as vol + +from homeassistant.components.sensor import PLATFORM_SCHEMA +from homeassistant.const import (TEMP_CELSIUS, CONF_DISPLAY_OPTIONS, CONF_NAME) +import homeassistant.helpers.config_validation as cv +from homeassistant.helpers.entity import Entity +from homeassistant.util import Throttle + +REQUIREMENTS = ['envirophat==0.0.6'] + +_LOGGER = logging.getLogger(__name__) + +DEFAULT_NAME = 'envirophat' +CONF_USE_LEDS = 'use_leds' + +MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=60) + +SENSOR_TYPES = { + 'light': ['light', ' ', 'mdi:weather-sunny'], + 'light_red': ['light_red', ' ', 'mdi:invert-colors'], + 'light_green': ['light_green', ' ', 'mdi:invert-colors'], + 'light_blue': ['light_blue', ' ', 'mdi:invert-colors'], + 'accelerometer_x': ['accelerometer_x', 'G', 'mdi:earth'], + 'accelerometer_y': ['accelerometer_y', 'G', 'mdi:earth'], + 'accelerometer_z': ['accelerometer_z', 'G', 'mdi:earth'], + 'magnetometer_x': ['magnetometer_x', ' ', 'mdi:magnet'], + 'magnetometer_y': ['magnetometer_y', ' ', 'mdi:magnet'], + 'magnetometer_z': ['magnetometer_z', ' ', 'mdi:magnet'], + 'temperature': ['temperature', TEMP_CELSIUS, 'mdi:thermometer'], + 'pressure': ['pressure', 'hPa', 'mdi:gauge'], + 'voltage_0': ['voltage_0', 'V', 'mdi:flash'], + 'voltage_1': ['voltage_1', 'V', 'mdi:flash'], + 'voltage_2': ['voltage_2', 'V', 'mdi:flash'], + 'voltage_3': ['voltage_3', 'V', 'mdi:flash'], +} + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_DISPLAY_OPTIONS, default=SENSOR_TYPES): + [vol.In(SENSOR_TYPES)], + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + vol.Optional(CONF_USE_LEDS, default=False): cv.boolean +}) + + +def setup_platform(hass, config, add_devices, discovery_info=None): + """Set up the Sense HAT sensor platform.""" + data = EnvirophatData(config.get(CONF_USE_LEDS)) + + dev = [] + for variable in config[CONF_DISPLAY_OPTIONS]: + dev.append(EnvirophatSensor(data, variable)) + + add_devices(dev, True) + + +class EnvirophatSensor(Entity): + """Representation of an Enviro pHAT sensor.""" + + def __init__(self, data, sensor_types): + """Initialize the sensor.""" + self.data = data + self._name = SENSOR_TYPES[sensor_types][0] + self._unit_of_measurement = SENSOR_TYPES[sensor_types][1] + self.type = sensor_types + 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 + + @property + def icon(self): + """Icon to use in the frontend, if any.""" + return SENSOR_TYPES[self.type][2] + + @property + def unit_of_measurement(self): + """Return the unit the value is expressed in.""" + return self._unit_of_measurement + + def update(self): + """Get the latest data and updates the states.""" + self.data.update() + if not self.data.light: + _LOGGER.error("Didn't receive data") + return + + if self.type == 'light': + self._state = self.data.light + if self.type == 'light_red': + self._state = self.data.light_red + if self.type == 'light_green': + self._state = self.data.light_green + if self.type == 'light_blue': + self._state = self.data.light_blue + if self.type == 'accelerometer_x': + self._state = self.data.accelerometer_x + if self.type == 'accelerometer_y': + self._state = self.data.accelerometer_y + if self.type == 'accelerometer_z': + self._state = self.data.accelerometer_z + if self.type == 'magnetometer_x': + self._state = self.data.magnetometer_x + if self.type == 'magnetometer_y': + self._state = self.data.magnetometer_y + if self.type == 'magnetometer_z': + self._state = self.data.magnetometer_z + if self.type == 'temperature': + self._state = self.data.temperature + if self.type == 'pressure': + self._state = self.data.pressure + if self.type == 'voltage_0': + self._state = self.data.voltage_0 + if self.type == 'voltage_1': + self._state = self.data.voltage_1 + if self.type == 'voltage_2': + self._state = self.data.voltage_2 + if self.type == 'voltage_3': + self._state = self.data.voltage_3 + + +class EnvirophatData(object): + """Get the latest data and update.""" + + def __init__(self, use_leds): + """Initialize the data object.""" + self.use_leds = use_leds + # sensors readings + self.light = None + self.light_red = None + self.light_green = None + self.light_blue = None + self.accelerometer_x = None + self.accelerometer_y = None + self.accelerometer_z = None + self.magnetometer_x = None + self.magnetometer_y = None + self.magnetometer_z = None + self.temperature = None + self.pressure = None + self.voltage_0 = None + self.voltage_1 = None + self.voltage_2 = None + self.voltage_3 = None + + @Throttle(MIN_TIME_BETWEEN_UPDATES) + def update(self): + """Get the latest data from Enviro pHAT.""" + from envirophat import analog, leds, light, motion, weather + + # Light sensor reading: 16-bit integer + self.light = light.light() + if self.use_leds: + # pylint: disable=no-value-for-parameter + leds.on() + # the three color values scaled agains the overall light, 0-255 + self.light_red, self.light_green, self.light_blue = light.rgb() + if self.use_leds: + # pylint: disable=no-value-for-parameter + leds.off() + + # accelerometer readings in G + self.accelerometer_x, self.accelerometer_y, self.accelerometer_z = \ + motion.accelerometer() + + # raw magnetometer reading + self.magnetometer_x, self.magnetometer_y, self.magnetometer_z = \ + motion.magnetometer() + + # temperature resolution of BMP280 sensor: 0.01°C + self.temperature = round(weather.temperature(), 2) + + # pressure resolution of BMP280 sensor: 0.16 Pa, rounding to 0.1 Pa + # with conversion to 100 Pa = 1 hPa + self.pressure = round(weather.pressure() / 100.0, 3) + + # Voltage sensor, reading between 0-3.3V + self.voltage_0, self.voltage_1, self.voltage_2, self.voltage_3 = \ + analog.read_all() diff --git a/requirements_all.txt b/requirements_all.txt index 022c147c2b4..9d3be36d135 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -165,6 +165,9 @@ eliqonline==1.0.13 # homeassistant.components.enocean enocean==0.31 +# homeassistant.components.sensor.envirophat +envirophat==0.0.6 + # homeassistant.components.keyboard_remote # evdev==0.6.1