core/homeassistant/components/light/decora_wifi.py

154 lines
5.0 KiB
Python

"""
Interfaces with the myLeviton API for Decora Smart WiFi products.
See:
http://www.leviton.com/en/products/lighting-controls/decora-smart-with-wifi
Uses Leviton's cloud services API for cloud-to-cloud integration.
"""
import logging
import voluptuous as vol
from homeassistant.components.light import (
ATTR_BRIGHTNESS, ATTR_TRANSITION, Light,
PLATFORM_SCHEMA, SUPPORT_BRIGHTNESS, SUPPORT_TRANSITION)
from homeassistant.const import (
CONF_USERNAME, CONF_PASSWORD,
EVENT_HOMEASSISTANT_STOP)
import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['decora_wifi==1.3']
_LOGGER = logging.getLogger(__name__)
# Validation of the user's configuration
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
})
NOTIFICATION_ID = 'leviton_notification'
NOTIFICATION_TITLE = 'myLeviton Decora Setup'
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Decora WiFi platform."""
# pylint: disable=import-error, no-name-in-module
from decora_wifi import DecoraWiFiSession
from decora_wifi.models.person import Person
from decora_wifi.models.residential_account import ResidentialAccount
from decora_wifi.models.residence import Residence
email = config.get(CONF_USERNAME)
password = config.get(CONF_PASSWORD)
session = DecoraWiFiSession()
try:
success = session.login(email, password)
# If login failed, notify user.
if success is None:
msg = 'Failed to log into myLeviton Services. Check credentials.'
_LOGGER.error(msg)
hass.components.persistent_notification.create(
msg, title=NOTIFICATION_TITLE, notification_id=NOTIFICATION_ID)
return False
# Gather all the available devices...
perms = session.user.get_residential_permissions()
all_switches = []
for permission in perms:
if permission.residentialAccountId is not None:
acct = ResidentialAccount(
session, permission.residentialAccountId)
for residence in acct.get_residences():
for switch in residence.get_iot_switches():
all_switches.append(switch)
elif permission.residenceId is not None:
residence = Residence(session, permission.residenceId)
for switch in residence.get_iot_switches():
all_switches.append(switch)
add_entities(DecoraWifiLight(sw) for sw in all_switches)
except ValueError:
_LOGGER.error('Failed to communicate with myLeviton Service.')
# Listen for the stop event and log out.
def logout(event):
"""Log out..."""
try:
if session is not None:
Person.logout(session)
except ValueError:
_LOGGER.error('Failed to log out of myLeviton Service.')
hass.bus.listen(EVENT_HOMEASSISTANT_STOP, logout)
class DecoraWifiLight(Light):
"""Representation of a Decora WiFi switch."""
def __init__(self, switch):
"""Initialize the switch."""
self._switch = switch
@property
def supported_features(self):
"""Return supported features."""
if self._switch.canSetLevel:
return SUPPORT_BRIGHTNESS | SUPPORT_TRANSITION
return 0
@property
def name(self):
"""Return the display name of this switch."""
return self._switch.name
@property
def brightness(self):
"""Return the brightness of the dimmer switch."""
return int(self._switch.brightness * 255 / 100)
@property
def is_on(self):
"""Return true if switch is on."""
return self._switch.power == 'ON'
def turn_on(self, **kwargs):
"""Instruct the switch to turn on & adjust brightness."""
attribs = {'power': 'ON'}
if ATTR_BRIGHTNESS in kwargs:
min_level = self._switch.data.get('minLevel', 0)
max_level = self._switch.data.get('maxLevel', 100)
brightness = int(kwargs[ATTR_BRIGHTNESS] * max_level / 255)
brightness = max(brightness, min_level)
attribs['brightness'] = brightness
if ATTR_TRANSITION in kwargs:
transition = int(kwargs[ATTR_TRANSITION])
attribs['fadeOnTime'] = attribs['fadeOffTime'] = transition
try:
self._switch.update_attributes(attribs)
except ValueError:
_LOGGER.error('Failed to turn on myLeviton switch.')
def turn_off(self, **kwargs):
"""Instruct the switch to turn off."""
attribs = {'power': 'OFF'}
try:
self._switch.update_attributes(attribs)
except ValueError:
_LOGGER.error('Failed to turn off myLeviton switch.')
def update(self):
"""Fetch new state data for this switch."""
try:
self._switch.refresh()
except ValueError:
_LOGGER.error('Failed to update myLeviton switch data.')