Add new SmartHab light and cover platform (#21225)

* Add SmartHab platform

* Remove url config entry, improve error handling

* Upgrade smarthab dependency

* Address comments

* Lint
This commit is contained in:
Baptiste Candellier 2019-05-13 12:35:31 +02:00 committed by Paulus Schoutsen
parent 1e22c8daca
commit 1a051f038d
7 changed files with 246 additions and 0 deletions

View File

@ -538,6 +538,7 @@ omit =
homeassistant/components/slack/notify.py
homeassistant/components/sma/sensor.py
homeassistant/components/smappee/*
homeassistant/components/smarthab/*
homeassistant/components/smtp/notify.py
homeassistant/components/snapcast/media_player.py
homeassistant/components/snmp/*

View File

@ -205,6 +205,7 @@ homeassistant/components/shiftr/* @fabaff
homeassistant/components/shodan/* @fabaff
homeassistant/components/simplisafe/* @bachya
homeassistant/components/sma/* @kellerza
homeassistant/components/smarthab/* @outadoc
homeassistant/components/smartthings/* @andrewsayre
homeassistant/components/smtp/* @fabaff
homeassistant/components/sonos/* @amelchio

View File

@ -0,0 +1,61 @@
"""
Support for SmartHab device integration.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/smarthab/
"""
import logging
import voluptuous as vol
from homeassistant.helpers.discovery import load_platform
from homeassistant.const import CONF_EMAIL, CONF_PASSWORD
import homeassistant.helpers.config_validation as cv
DOMAIN = 'smarthab'
DATA_HUB = 'hub'
_LOGGER = logging.getLogger(__name__)
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
vol.Required(CONF_EMAIL): cv.string,
vol.Required(CONF_PASSWORD): cv.string
}),
}, extra=vol.ALLOW_EXTRA)
def setup(hass, config) -> bool:
"""Set up the SmartHab platform."""
import pysmarthab
sh_conf = config.get(DOMAIN)
# Assign configuration variables
username = sh_conf[CONF_EMAIL]
password = sh_conf[CONF_PASSWORD]
# Setup connection with SmartHab API
hub = pysmarthab.SmartHab()
try:
hub.login(username, password)
except pysmarthab.RequestFailedException as ex:
_LOGGER.error("Error while trying to reach SmartHab API.")
_LOGGER.debug(ex, exc_info=True)
return False
# Verify that passed in configuration works
if not hub.is_logged_in():
_LOGGER.error("Could not authenticate with SmartHab API")
return False
# Pass hub object to child platforms
hass.data[DOMAIN] = {
DATA_HUB: hub
}
load_platform(hass, 'light', DOMAIN, None, config)
load_platform(hass, 'cover', DOMAIN, None, config)
return True

View File

@ -0,0 +1,100 @@
"""
Support for SmartHab device integration.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/smarthab/
"""
import logging
from datetime import timedelta
from requests.exceptions import Timeout
from homeassistant.components.cover import (
CoverDevice, SUPPORT_OPEN, SUPPORT_CLOSE, SUPPORT_SET_POSITION,
ATTR_POSITION
)
from . import DOMAIN, DATA_HUB
_LOGGER = logging.getLogger(__name__)
SCAN_INTERVAL = timedelta(seconds=60)
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the SmartHab roller shutters platform."""
import pysmarthab
hub = hass.data[DOMAIN][DATA_HUB]
devices = hub.get_device_list()
_LOGGER.debug("Found a total of %s devices", str(len(devices)))
entities = (SmartHabCover(cover)
for cover in devices if isinstance(cover, pysmarthab.Shutter))
add_entities(entities, True)
class SmartHabCover(CoverDevice):
"""Representation a cover."""
def __init__(self, cover):
"""Initialize a SmartHabCover."""
self._cover = cover
@property
def unique_id(self) -> str:
"""Return a unique ID."""
return self._cover.device_id
@property
def name(self) -> str:
"""Return the display name of this light."""
return self._cover.label
@property
def current_cover_position(self) -> int:
"""Return current position of cover.
None is unknown, 0 is closed, 100 is fully open.
"""
return self._cover.state
@property
def supported_features(self) -> int:
"""Flag supported features."""
supported_features = SUPPORT_OPEN | SUPPORT_CLOSE
if self.current_cover_position is not None:
supported_features |= SUPPORT_SET_POSITION
return supported_features
@property
def is_closed(self) -> bool:
"""Return if the cover is closed or not."""
return self._cover.state == 0
@property
def device_class(self) -> str:
"""Return the class of this device, from component DEVICE_CLASSES."""
return 'window'
def open_cover(self, **kwargs):
"""Open the cover."""
self._cover.open()
def close_cover(self, **kwargs):
"""Close cover."""
self._cover.close()
def set_cover_position(self, **kwargs):
"""Move the cover to a specific position."""
self._cover.state = kwargs[ATTR_POSITION]
def update(self):
"""Fetch new state data for this cover."""
try:
self._cover.update()
except Timeout:
_LOGGER.error("Reached timeout while updating cover %s from API",
self.entity_id)

View File

@ -0,0 +1,70 @@
"""
Support for SmartHab device integration.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/smarthab/
"""
import logging
from datetime import timedelta
from requests.exceptions import Timeout
from homeassistant.components.light import Light
from . import DOMAIN, DATA_HUB
_LOGGER = logging.getLogger(__name__)
SCAN_INTERVAL = timedelta(seconds=60)
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the SmartHab lights platform."""
import pysmarthab
hub = hass.data[DOMAIN][DATA_HUB]
devices = hub.get_device_list()
_LOGGER.debug("Found a total of %s devices", str(len(devices)))
entities = (SmartHabLight(light)
for light in devices if isinstance(light, pysmarthab.Light))
add_entities(entities, True)
class SmartHabLight(Light):
"""Representation of a SmartHab Light."""
def __init__(self, light):
"""Initialize a SmartHabLight."""
self._light = light
@property
def unique_id(self) -> str:
"""Return a unique ID."""
return self._light.device_id
@property
def name(self) -> str:
"""Return the display name of this light."""
return self._light.label
@property
def is_on(self) -> bool:
"""Return true if light is on."""
return self._light.state
def turn_on(self, **kwargs):
"""Instruct the light to turn on."""
self._light.turn_on()
def turn_off(self, **kwargs):
"""Instruct the light to turn off."""
self._light.turn_off()
def update(self):
"""Fetch new state data for this light."""
try:
self._light.update()
except Timeout:
_LOGGER.error("Reached timeout while updating light %s from API",
self.entity_id)

View File

@ -0,0 +1,10 @@
{
"domain": "smarthab",
"name": "SmartHab",
"documentation": "https://www.home-assistant.io/components/smarthab",
"requirements": [
"smarthab==0.20"
],
"dependencies": [],
"codeowners": ["@outadoc"]
}

View File

@ -1617,6 +1617,9 @@ slixmpp==1.4.2
# homeassistant.components.smappee
smappy==0.2.16
# homeassistant.components.smarthab
smarthab==0.20
# homeassistant.components.bh1750
# homeassistant.components.bme280
# homeassistant.components.bme680