Make MyQ platform async (#18489)

* Make MyQ platform async

* Bumped requirements

* Member comments

* Member updates
pull/18557/head
Aaron Bach 2018-11-18 10:37:03 -07:00 committed by Martin Hjelmare
parent dfb8f60fe2
commit 8f59be2059
2 changed files with 41 additions and 62 deletions

View File

@ -9,18 +9,15 @@ import logging
import voluptuous as vol import voluptuous as vol
from homeassistant.components.cover import ( from homeassistant.components.cover import (
CoverDevice, SUPPORT_CLOSE, SUPPORT_OPEN) PLATFORM_SCHEMA, SUPPORT_CLOSE, SUPPORT_OPEN, CoverDevice)
from homeassistant.const import ( from homeassistant.const import (
CONF_PASSWORD, CONF_TYPE, CONF_USERNAME, STATE_CLOSED, STATE_CLOSING, CONF_PASSWORD, CONF_TYPE, CONF_USERNAME, STATE_CLOSED, STATE_CLOSING,
STATE_OPEN, STATE_OPENING) STATE_OPEN, STATE_OPENING)
import homeassistant.helpers.config_validation as cv from homeassistant.helpers import aiohttp_client, config_validation as cv
REQUIREMENTS = ['pymyq==0.0.15']
REQUIREMENTS = ['pymyq==1.0.0']
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
DEFAULT_NAME = 'myq'
MYQ_TO_HASS = { MYQ_TO_HASS = {
'closed': STATE_CLOSED, 'closed': STATE_CLOSED,
'closing': STATE_CLOSING, 'closing': STATE_CLOSING,
@ -28,95 +25,69 @@ MYQ_TO_HASS = {
'opening': STATE_OPENING 'opening': STATE_OPENING
} }
NOTIFICATION_ID = 'myq_notification' PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
NOTIFICATION_TITLE = 'MyQ Cover Setup'
COVER_SCHEMA = vol.Schema({
vol.Required(CONF_TYPE): cv.string, vol.Required(CONF_TYPE): cv.string,
vol.Required(CONF_USERNAME): cv.string, vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string vol.Required(CONF_PASSWORD): cv.string
}) })
def setup_platform(hass, config, add_entities, discovery_info=None): async def async_setup_platform(
"""Set up the MyQ component.""" hass, config, async_add_entities, discovery_info=None):
from pymyq import MyQAPI as pymyq """Set up the platform."""
from pymyq import login
from pymyq.errors import MyQError, UnsupportedBrandError
username = config.get(CONF_USERNAME) websession = aiohttp_client.async_get_clientsession(hass)
password = config.get(CONF_PASSWORD)
brand = config.get(CONF_TYPE) username = config[CONF_USERNAME]
myq = pymyq(username, password, brand) password = config[CONF_PASSWORD]
brand = config[CONF_TYPE]
try: try:
if not myq.is_supported_brand(): myq = await login(username, password, brand, websession)
raise ValueError("Unsupported type. See documentation") except UnsupportedBrandError:
_LOGGER.error('Unsupported brand: %s', brand)
return
except MyQError as err:
_LOGGER.error('There was an error while logging in: %s', err)
return
if not myq.is_login_valid(): devices = await myq.get_devices()
raise ValueError("Username or Password is incorrect") async_add_entities([MyQDevice(device) for device in devices], True)
add_entities(MyQDevice(myq, door) for door in myq.get_garage_doors())
return True
except (TypeError, KeyError, NameError, ValueError) as ex:
_LOGGER.error("%s", ex)
hass.components.persistent_notification.create(
'Error: {}<br />'
'You will need to restart hass after fixing.'
''.format(ex),
title=NOTIFICATION_TITLE,
notification_id=NOTIFICATION_ID)
return False
class MyQDevice(CoverDevice): class MyQDevice(CoverDevice):
"""Representation of a MyQ cover.""" """Representation of a MyQ cover."""
def __init__(self, myq, device): def __init__(self, device):
"""Initialize with API object, device id.""" """Initialize with API object, device id."""
self.myq = myq self._device = device
self.device_id = device['deviceid']
self._name = device['name']
self._status = None
@property @property
def device_class(self): def device_class(self):
"""Define this cover as a garage door.""" """Define this cover as a garage door."""
return 'garage' return 'garage'
@property
def should_poll(self):
"""Poll for state."""
return True
@property @property
def name(self): def name(self):
"""Return the name of the garage door if any.""" """Return the name of the garage door if any."""
return self._name if self._name else DEFAULT_NAME return self._device.name
@property @property
def is_closed(self): def is_closed(self):
"""Return true if cover is closed, else False.""" """Return true if cover is closed, else False."""
if self._status in [None, False]: return MYQ_TO_HASS.get(self._device.state) == STATE_CLOSED
return None
return MYQ_TO_HASS.get(self._status) == STATE_CLOSED
@property @property
def is_closing(self): def is_closing(self):
"""Return if the cover is closing or not.""" """Return if the cover is closing or not."""
return MYQ_TO_HASS.get(self._status) == STATE_CLOSING return MYQ_TO_HASS.get(self._device.state) == STATE_CLOSING
@property @property
def is_opening(self): def is_opening(self):
"""Return if the cover is opening or not.""" """Return if the cover is opening or not."""
return MYQ_TO_HASS.get(self._status) == STATE_OPENING return MYQ_TO_HASS.get(self._device.state) == STATE_OPENING
def close_cover(self, **kwargs):
"""Issue close command to cover."""
self.myq.close_device(self.device_id)
def open_cover(self, **kwargs):
"""Issue open command to cover."""
self.myq.open_device(self.device_id)
@property @property
def supported_features(self): def supported_features(self):
@ -126,8 +97,16 @@ class MyQDevice(CoverDevice):
@property @property
def unique_id(self): def unique_id(self):
"""Return a unique, HASS-friendly identifier for this entity.""" """Return a unique, HASS-friendly identifier for this entity."""
return self.device_id return self._device.device_id
def update(self): async def async_close_cover(self, **kwargs):
"""Issue close command to cover."""
await self._device.close()
async def async_open_cover(self, **kwargs):
"""Issue open command to cover."""
await self._device.open()
async def async_update(self):
"""Update status of cover.""" """Update status of cover."""
self._status = self.myq.get_status(self.device_id) await self._device.update()

View File

@ -1044,7 +1044,7 @@ pymonoprice==0.3
pymusiccast==0.1.6 pymusiccast==0.1.6
# homeassistant.components.cover.myq # homeassistant.components.cover.myq
pymyq==0.0.15 pymyq==1.0.0
# homeassistant.components.mysensors # homeassistant.components.mysensors
pymysensors==0.18.0 pymysensors==0.18.0