Files
ha-core/homeassistant/components/slide/__init__.py
Alexander 330ae0d885 Add support Slide cover (#25913)
* Add support GoSlide cover

* Fixed Parameters differ from overridden
Fixed Removed other pylint warnings

* Renamed GoSlide to Slide, because of Innovation in Motion rebranding

* Fixed codeowners file

* Fixed requirements file

* Removed pylint: disable=unused-argument
Removed DOMAIN not exist check
Changed if to min/max
Changed 3rd party import to top of the module
Removed timeout/retry parameters
Removed unused constants
Added check for discovery_info is none
Changed pass slide object instead of full hass object
Changed pass api object instead of full hass object
Added unique_id functionality
Removed entity_id/name properties
Removed supported_features/state functions

* Fixed unused variables

* Changed Slide API uses snake names
Changed Improved exception handling
Changed Updated Slide API to 0.50.0

* Changed moved exceptions into goslide-api
Changed retry setup into coroutine

* Changed str(err) to err
Changed invert if result to if not result
2019-09-03 10:09:25 -07:00

158 lines
5.0 KiB
Python
Executable File

"""Component for the Go Slide API."""
import logging
from datetime import timedelta
import voluptuous as vol
from goslideapi import GoSlideCloud, goslideapi
from homeassistant.const import (
CONF_USERNAME,
CONF_PASSWORD,
CONF_SCAN_INTERVAL,
STATE_OPEN,
STATE_CLOSED,
STATE_OPENING,
STATE_CLOSING,
)
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.discovery import async_load_platform
from homeassistant.helpers.event import async_track_time_interval, async_call_later
from .const import DOMAIN, SLIDES, API, COMPONENT, DEFAULT_RETRY
_LOGGER = logging.getLogger(__name__)
DEFAULT_SCAN_INTERVAL = timedelta(seconds=30)
CONFIG_SCHEMA = vol.Schema(
{
DOMAIN: vol.Schema(
{
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(
CONF_SCAN_INTERVAL, default=DEFAULT_SCAN_INTERVAL
): cv.time_period,
}
)
},
extra=vol.ALLOW_EXTRA,
)
async def async_setup(hass, config):
"""Set up the Slide platform."""
async def update_slides(now=None):
"""Update slide information."""
result = await hass.data[DOMAIN][API].slides_overview()
if result is None:
_LOGGER.error("Slide API does not work or returned an error")
return
if result:
_LOGGER.debug("Slide API returned %d slide(s)", len(result))
else:
_LOGGER.warning("Slide API returned 0 slides")
for slide in result:
if "device_id" not in slide:
_LOGGER.error(
"Found invalid Slide entry, device_id is " "missing. Entry=%s",
slide,
)
continue
uid = slide["device_id"].replace("slide_", "")
slidenew = hass.data[DOMAIN][SLIDES].setdefault(uid, {})
slidenew["mac"] = uid
slidenew["id"] = slide["id"]
slidenew["name"] = slide["device_name"]
slidenew["state"] = None
oldpos = slidenew.get("pos")
slidenew["pos"] = None
slidenew["online"] = False
if "device_info" not in slide:
_LOGGER.error(
"Slide %s (%s) has no device_info Entry=%s",
slide["id"],
slidenew["mac"],
slide,
)
continue
# Check if we have pos (OK) or code (NOK)
if "pos" in slide["device_info"]:
slidenew["online"] = True
slidenew["pos"] = slide["device_info"]["pos"]
slidenew["pos"] = max(0, min(1, slidenew["pos"]))
if oldpos is None or oldpos == slidenew["pos"]:
slidenew["state"] = (
STATE_CLOSED if slidenew["pos"] > 0.95 else STATE_OPEN
)
elif oldpos < slidenew["pos"]:
slidenew["state"] = (
STATE_CLOSED if slidenew["pos"] >= 0.95 else STATE_CLOSING
)
else:
slidenew["state"] = (
STATE_OPEN if slidenew["pos"] <= 0.05 else STATE_OPENING
)
elif "code" in slide["device_info"]:
_LOGGER.warning(
"Slide %s (%s) is offline with " "code=%s",
slide["id"],
slidenew["mac"],
slide["device_info"]["code"],
)
else:
_LOGGER.error(
"Slide %s (%s) has invalid device_info %s",
slide["id"],
slidenew["mac"],
slide["device_info"],
)
_LOGGER.debug("Updated entry=%s", slidenew)
async def retry_setup(now):
"""Retry setup if a connection/timeout happens on Slide API."""
await async_setup(hass, config)
hass.data[DOMAIN] = {}
hass.data[DOMAIN][SLIDES] = {}
username = config[DOMAIN][CONF_USERNAME]
password = config[DOMAIN][CONF_PASSWORD]
scaninterval = config[DOMAIN][CONF_SCAN_INTERVAL]
hass.data[DOMAIN][API] = GoSlideCloud(username, password)
try:
result = await hass.data[DOMAIN][API].login()
except (goslideapi.ClientConnectionError, goslideapi.ClientTimeoutError) as err:
_LOGGER.error(
"Error connecting to Slide Cloud: %s, going to retry in %s seconds",
err,
DEFAULT_RETRY,
)
async_call_later(hass, DEFAULT_RETRY, retry_setup)
return True
if not result:
_LOGGER.error("Slide API returned unknown error during authentication")
return False
_LOGGER.debug("Slide API successfully authenticated")
await update_slides()
hass.async_create_task(async_load_platform(hass, COMPONENT, DOMAIN, {}, config))
async_track_time_interval(hass, update_slides, scaninterval)
return True