Embed all platforms into components (#20677)

* Consolidate all components with platforms

* Organize tests

* Fix more tests

* Fix Verisure tests

* one final test fix

* Add change

* Fix coverage
This commit is contained in:
Paulus Schoutsen 2019-02-02 07:13:16 -08:00 committed by GitHub
parent a24da611c5
commit e2d3c27e85
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
490 changed files with 255 additions and 517 deletions

View file

@ -0,0 +1,82 @@
"""
Support for Fibaro binary sensors.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.fibaro/
"""
import logging
from homeassistant.components.binary_sensor import (
BinarySensorDevice, ENTITY_ID_FORMAT)
from homeassistant.components.fibaro import (
FIBARO_DEVICES, FibaroDevice)
from homeassistant.const import (CONF_DEVICE_CLASS, CONF_ICON)
DEPENDENCIES = ['fibaro']
_LOGGER = logging.getLogger(__name__)
SENSOR_TYPES = {
'com.fibaro.floodSensor': ['Flood', 'mdi:water', 'flood'],
'com.fibaro.motionSensor': ['Motion', 'mdi:run', 'motion'],
'com.fibaro.doorSensor': ['Door', 'mdi:window-open', 'door'],
'com.fibaro.windowSensor': ['Window', 'mdi:window-open', 'window'],
'com.fibaro.smokeSensor': ['Smoke', 'mdi:smoking', 'smoke'],
'com.fibaro.FGMS001': ['Motion', 'mdi:run', 'motion'],
'com.fibaro.heatDetector': ['Heat', 'mdi:fire', 'heat'],
}
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Perform the setup for Fibaro controller devices."""
if discovery_info is None:
return
add_entities(
[FibaroBinarySensor(device)
for device in hass.data[FIBARO_DEVICES]['binary_sensor']], True)
class FibaroBinarySensor(FibaroDevice, BinarySensorDevice):
"""Representation of a Fibaro Binary Sensor."""
def __init__(self, fibaro_device):
"""Initialize the binary_sensor."""
self._state = None
super().__init__(fibaro_device)
self.entity_id = ENTITY_ID_FORMAT.format(self.ha_id)
stype = None
devconf = fibaro_device.device_config
if fibaro_device.type in SENSOR_TYPES:
stype = fibaro_device.type
elif fibaro_device.baseType in SENSOR_TYPES:
stype = fibaro_device.baseType
if stype:
self._device_class = SENSOR_TYPES[stype][2]
self._icon = SENSOR_TYPES[stype][1]
else:
self._device_class = None
self._icon = None
# device_config overrides:
self._device_class = devconf.get(CONF_DEVICE_CLASS,
self._device_class)
self._icon = devconf.get(CONF_ICON, self._icon)
@property
def icon(self):
"""Icon to use in the frontend, if any."""
return self._icon
@property
def device_class(self):
"""Return the device class of the sensor."""
return self._device_class
@property
def is_on(self):
"""Return true if sensor is on."""
return self._state
def update(self):
"""Get the latest data and update the state."""
self._state = self.current_binary_state

View file

@ -0,0 +1,92 @@
"""
Support for Fibaro cover - curtains, rollershutters etc.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/cover.fibaro/
"""
import logging
from homeassistant.components.cover import (
CoverDevice, ENTITY_ID_FORMAT, ATTR_POSITION, ATTR_TILT_POSITION)
from homeassistant.components.fibaro import (
FIBARO_DEVICES, FibaroDevice)
DEPENDENCIES = ['fibaro']
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Fibaro covers."""
if discovery_info is None:
return
add_entities(
[FibaroCover(device) for
device in hass.data[FIBARO_DEVICES]['cover']], True)
class FibaroCover(FibaroDevice, CoverDevice):
"""Representation a Fibaro Cover."""
def __init__(self, fibaro_device):
"""Initialize the Vera device."""
super().__init__(fibaro_device)
self.entity_id = ENTITY_ID_FORMAT.format(self.ha_id)
@staticmethod
def bound(position):
"""Normalize the position."""
if position is None:
return None
position = int(position)
if position <= 5:
return 0
if position >= 95:
return 100
return position
@property
def current_cover_position(self):
"""Return current position of cover. 0 is closed, 100 is open."""
return self.bound(self.level)
@property
def current_cover_tilt_position(self):
"""Return the current tilt position for venetian blinds."""
return self.bound(self.level2)
def set_cover_position(self, **kwargs):
"""Move the cover to a specific position."""
self.set_level(kwargs.get(ATTR_POSITION))
def set_cover_tilt_position(self, **kwargs):
"""Move the cover to a specific position."""
self.set_level2(kwargs.get(ATTR_TILT_POSITION))
@property
def is_closed(self):
"""Return if the cover is closed."""
if self.current_cover_position is None:
return None
return self.current_cover_position == 0
def open_cover(self, **kwargs):
"""Open the cover."""
self.action("open")
def close_cover(self, **kwargs):
"""Close the cover."""
self.action("close")
def open_cover_tilt(self, **kwargs):
"""Open the cover tilt."""
self.set_level2(100)
def close_cover_tilt(self, **kwargs):
"""Close the cover."""
self.set_level2(0)
def stop_cover(self, **kwargs):
"""Stop the cover."""
self.action("stop")

View file

@ -0,0 +1,211 @@
"""
Support for Fibaro lights.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/light.fibaro/
"""
import logging
import asyncio
from functools import partial
from homeassistant.const import (
CONF_WHITE_VALUE)
from homeassistant.components.fibaro import (
FIBARO_DEVICES, FibaroDevice,
CONF_DIMMING, CONF_COLOR, CONF_RESET_COLOR)
from homeassistant.components.light import (
ATTR_BRIGHTNESS, ATTR_HS_COLOR, ATTR_WHITE_VALUE, ENTITY_ID_FORMAT,
SUPPORT_BRIGHTNESS, SUPPORT_COLOR, SUPPORT_WHITE_VALUE, Light)
import homeassistant.util.color as color_util
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['fibaro']
def scaleto255(value):
"""Scale the input value from 0-100 to 0-255."""
# Fibaro has a funny way of storing brightness either 0-100 or 0-99
# depending on device type (e.g. dimmer vs led)
if value > 98:
value = 100
return max(0, min(255, ((value * 255.0) / 100.0)))
def scaleto100(value):
"""Scale the input value from 0-255 to 0-100."""
# Make sure a low but non-zero value is not rounded down to zero
if 0 < value < 3:
return 1
return max(0, min(100, ((value * 100.0) / 255.0)))
async def async_setup_platform(hass,
config,
async_add_entities,
discovery_info=None):
"""Perform the setup for Fibaro controller devices."""
if discovery_info is None:
return
async_add_entities(
[FibaroLight(device)
for device in hass.data[FIBARO_DEVICES]['light']], True)
class FibaroLight(FibaroDevice, Light):
"""Representation of a Fibaro Light, including dimmable."""
def __init__(self, fibaro_device):
"""Initialize the light."""
self._brightness = None
self._color = (0, 0)
self._last_brightness = 0
self._supported_flags = 0
self._update_lock = asyncio.Lock()
self._white = 0
devconf = fibaro_device.device_config
self._reset_color = devconf.get(CONF_RESET_COLOR, False)
supports_color = 'color' in fibaro_device.properties and \
'setColor' in fibaro_device.actions
supports_dimming = 'levelChange' in fibaro_device.interfaces
supports_white_v = 'setW' in fibaro_device.actions
# Configuration can overrride default capability detection
if devconf.get(CONF_DIMMING, supports_dimming):
self._supported_flags |= SUPPORT_BRIGHTNESS
if devconf.get(CONF_COLOR, supports_color):
self._supported_flags |= SUPPORT_COLOR
if devconf.get(CONF_WHITE_VALUE, supports_white_v):
self._supported_flags |= SUPPORT_WHITE_VALUE
super().__init__(fibaro_device)
self.entity_id = ENTITY_ID_FORMAT.format(self.ha_id)
@property
def brightness(self):
"""Return the brightness of the light."""
return scaleto255(self._brightness)
@property
def hs_color(self):
"""Return the color of the light."""
return self._color
@property
def white_value(self):
"""Return the white value of this light between 0..255."""
return self._white
@property
def supported_features(self):
"""Flag supported features."""
return self._supported_flags
async def async_turn_on(self, **kwargs):
"""Turn the light on."""
async with self._update_lock:
await self.hass.async_add_executor_job(
partial(self._turn_on, **kwargs))
def _turn_on(self, **kwargs):
"""Really turn the light on."""
if self._supported_flags & SUPPORT_BRIGHTNESS:
target_brightness = kwargs.get(ATTR_BRIGHTNESS)
# No brightness specified, so we either restore it to
# last brightness or switch it on at maximum level
if target_brightness is None:
if self._brightness == 0:
if self._last_brightness:
self._brightness = self._last_brightness
else:
self._brightness = 100
else:
# We set it to the target brightness and turn it on
self._brightness = scaleto100(target_brightness)
if self._supported_flags & SUPPORT_COLOR:
if self._reset_color and \
kwargs.get(ATTR_WHITE_VALUE) is None and \
kwargs.get(ATTR_HS_COLOR) is None and \
kwargs.get(ATTR_BRIGHTNESS) is None:
self._color = (100, 0)
# Update based on parameters
self._white = kwargs.get(ATTR_WHITE_VALUE, self._white)
self._color = kwargs.get(ATTR_HS_COLOR, self._color)
rgb = color_util.color_hs_to_RGB(*self._color)
self.call_set_color(
round(rgb[0] * self._brightness / 100.0),
round(rgb[1] * self._brightness / 100.0),
round(rgb[2] * self._brightness / 100.0),
round(self._white * self._brightness / 100.0))
if self.state == 'off':
self.set_level(int(self._brightness))
return
if self._reset_color:
bri255 = scaleto255(self._brightness)
self.call_set_color(bri255, bri255, bri255, bri255)
if self._supported_flags & SUPPORT_BRIGHTNESS:
self.set_level(int(self._brightness))
return
# The simplest case is left for last. No dimming, just switch on
self.call_turn_on()
async def async_turn_off(self, **kwargs):
"""Turn the light off."""
async with self._update_lock:
await self.hass.async_add_executor_job(
partial(self._turn_off, **kwargs))
def _turn_off(self, **kwargs):
"""Really turn the light off."""
# Let's save the last brightness level before we switch it off
if (self._supported_flags & SUPPORT_BRIGHTNESS) and \
self._brightness and self._brightness > 0:
self._last_brightness = self._brightness
self._brightness = 0
self.call_turn_off()
@property
def is_on(self):
"""Return true if device is on."""
return self.current_binary_state
async def async_update(self):
"""Update the state."""
async with self._update_lock:
await self.hass.async_add_executor_job(self._update)
def _update(self):
"""Really update the state."""
# Brightness handling
if self._supported_flags & SUPPORT_BRIGHTNESS:
self._brightness = float(self.fibaro_device.properties.value)
# Fibaro might report 0-99 or 0-100 for brightness,
# based on device type, so we round up here
if self._brightness > 99:
self._brightness = 100
# Color handling
if self._supported_flags & SUPPORT_COLOR and \
'color' in self.fibaro_device.properties and \
',' in self.fibaro_device.properties.color:
# Fibaro communicates the color as an 'R, G, B, W' string
rgbw_s = self.fibaro_device.properties.color
if rgbw_s == '0,0,0,0' and\
'lastColorSet' in self.fibaro_device.properties:
rgbw_s = self.fibaro_device.properties.lastColorSet
rgbw_list = [int(i) for i in rgbw_s.split(",")][:4]
if rgbw_list[0] or rgbw_list[1] or rgbw_list[2]:
self._color = color_util.color_RGB_to_hs(*rgbw_list[:3])
if (self._supported_flags & SUPPORT_WHITE_VALUE) and \
self.brightness != 0:
self._white = min(255, max(0, rgbw_list[3]*100.0 /
self._brightness))

View file

@ -0,0 +1,35 @@
"""
Support for Fibaro scenes.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/scene.fibaro/
"""
import logging
from homeassistant.components.scene import (
Scene)
from homeassistant.components.fibaro import (
FIBARO_DEVICES, FibaroDevice)
DEPENDENCIES = ['fibaro']
_LOGGER = logging.getLogger(__name__)
async def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
"""Perform the setup for Fibaro scenes."""
if discovery_info is None:
return
async_add_entities(
[FibaroScene(scene)
for scene in hass.data[FIBARO_DEVICES]['scene']], True)
class FibaroScene(FibaroDevice, Scene):
"""Representation of a Fibaro scene entity."""
def activate(self):
"""Activate the scene."""
self.fibaro_device.start()

View file

@ -0,0 +1,99 @@
"""
Support for Fibaro sensors.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/sensor.fibaro/
"""
import logging
from homeassistant.const import (
DEVICE_CLASS_TEMPERATURE, DEVICE_CLASS_HUMIDITY,
DEVICE_CLASS_ILLUMINANCE, TEMP_CELSIUS, TEMP_FAHRENHEIT)
from homeassistant.helpers.entity import Entity
from homeassistant.components.sensor import ENTITY_ID_FORMAT
from homeassistant.components.fibaro import (
FIBARO_DEVICES, FibaroDevice)
SENSOR_TYPES = {
'com.fibaro.temperatureSensor':
['Temperature', None, None, DEVICE_CLASS_TEMPERATURE],
'com.fibaro.smokeSensor':
['Smoke', 'ppm', 'mdi:fire', None],
'CO2':
['CO2', 'ppm', 'mdi:cloud', None],
'com.fibaro.humiditySensor':
['Humidity', '%', None, DEVICE_CLASS_HUMIDITY],
'com.fibaro.lightSensor':
['Light', 'lx', None, DEVICE_CLASS_ILLUMINANCE]
}
DEPENDENCIES = ['fibaro']
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Fibaro controller devices."""
if discovery_info is None:
return
add_entities(
[FibaroSensor(device)
for device in hass.data[FIBARO_DEVICES]['sensor']], True)
class FibaroSensor(FibaroDevice, Entity):
"""Representation of a Fibaro Sensor."""
def __init__(self, fibaro_device):
"""Initialize the sensor."""
self.current_value = None
self.last_changed_time = None
super().__init__(fibaro_device)
self.entity_id = ENTITY_ID_FORMAT.format(self.ha_id)
if fibaro_device.type in SENSOR_TYPES:
self._unit = SENSOR_TYPES[fibaro_device.type][1]
self._icon = SENSOR_TYPES[fibaro_device.type][2]
self._device_class = SENSOR_TYPES[fibaro_device.type][3]
else:
self._unit = None
self._icon = None
self._device_class = None
try:
if not self._unit:
if self.fibaro_device.properties.unit == 'lux':
self._unit = 'lx'
elif self.fibaro_device.properties.unit == 'C':
self._unit = TEMP_CELSIUS
elif self.fibaro_device.properties.unit == 'F':
self._unit = TEMP_FAHRENHEIT
else:
self._unit = self.fibaro_device.properties.unit
except (KeyError, ValueError):
pass
@property
def state(self):
"""Return the state of the sensor."""
return self.current_value
@property
def unit_of_measurement(self):
"""Return the unit of measurement of this entity, if any."""
return self._unit
@property
def icon(self):
"""Icon to use in the frontend, if any."""
return self._icon
@property
def device_class(self):
"""Return the device class of the sensor."""
return self._device_class
def update(self):
"""Update the state."""
try:
self.current_value = float(self.fibaro_device.properties.value)
except (KeyError, ValueError):
pass

View file

@ -0,0 +1,68 @@
"""
Support for Fibaro switches.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/switch.fibaro/
"""
import logging
from homeassistant.util import convert
from homeassistant.components.switch import ENTITY_ID_FORMAT, SwitchDevice
from homeassistant.components.fibaro import (
FIBARO_DEVICES, FibaroDevice)
DEPENDENCIES = ['fibaro']
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Fibaro switches."""
if discovery_info is None:
return
add_entities(
[FibaroSwitch(device) for
device in hass.data[FIBARO_DEVICES]['switch']], True)
class FibaroSwitch(FibaroDevice, SwitchDevice):
"""Representation of a Fibaro Switch."""
def __init__(self, fibaro_device):
"""Initialize the Fibaro device."""
self._state = False
super().__init__(fibaro_device)
self.entity_id = ENTITY_ID_FORMAT.format(self.ha_id)
def turn_on(self, **kwargs):
"""Turn device on."""
self.call_turn_on()
self._state = True
def turn_off(self, **kwargs):
"""Turn device off."""
self.call_turn_off()
self._state = False
@property
def current_power_w(self):
"""Return the current power usage in W."""
if 'power' in self.fibaro_device.interfaces:
return convert(self.fibaro_device.properties.power, float, 0.0)
return None
@property
def today_energy_kwh(self):
"""Return the today total energy usage in kWh."""
if 'energy' in self.fibaro_device.interfaces:
return convert(self.fibaro_device.properties.energy, float, 0.0)
return None
@property
def is_on(self):
"""Return true if device is on."""
return self._state
def update(self):
"""Update device state."""
self._state = self.current_binary_state