core/homeassistant/components/sleepiq/__init__.py

116 lines
3.2 KiB
Python
Raw Normal View History

"""Support for SleepIQ from SleepNumber."""
from datetime import timedelta
import logging
from sleepyq import Sleepyq
import voluptuous as vol
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import discovery
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.typing import ConfigType
from homeassistant.util import Throttle
from .const import DOMAIN
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=30)
_LOGGER = logging.getLogger(__name__)
2019-07-31 19:25:30 +00:00
CONFIG_SCHEMA = vol.Schema(
{
vol.Required(DOMAIN): vol.Schema(
{
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
}
)
},
extra=vol.ALLOW_EXTRA,
)
def setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the SleepIQ component.
Will automatically load sensor components to support
devices discovered on the account.
"""
username = config[DOMAIN][CONF_USERNAME]
password = config[DOMAIN][CONF_PASSWORD]
client = Sleepyq(username, password)
try:
data = SleepIQData(client)
data.update()
except ValueError:
message = """
SleepIQ failed to login, double check your username and password"
"""
_LOGGER.error(message)
return False
hass.data[DOMAIN] = data
discovery.load_platform(hass, Platform.SENSOR, DOMAIN, {}, config)
discovery.load_platform(hass, Platform.BINARY_SENSOR, DOMAIN, {}, config)
return True
class SleepIQData:
"""Get the latest data from SleepIQ."""
def __init__(self, client):
"""Initialize the data object."""
self._client = client
self.beds = {}
self.update()
@Throttle(MIN_TIME_BETWEEN_UPDATES)
def update(self):
"""Get the latest data from SleepIQ."""
self._client.login()
beds = self._client.beds_with_sleeper_status()
self.beds = {bed.bed_id: bed for bed in beds}
class SleepIQSensor(Entity):
"""Implementation of a SleepIQ sensor."""
def __init__(self, sleepiq_data, bed_id, side):
"""Initialize the sensor."""
self._bed_id = bed_id
self._side = side
self.sleepiq_data = sleepiq_data
self.side = None
self.bed = None
# added by subclass
self._name = None
self.type = None
@property
def name(self):
"""Return the name of the sensor."""
2019-07-31 19:25:30 +00:00
return "SleepNumber {} {} {}".format(
self.bed.name, self.side.sleeper.first_name, self._name
)
@property
def unique_id(self):
"""Return a unique ID for the bed."""
return f"{self._bed_id}-{self._side}-{self.type}"
def update(self):
"""Get the latest data from SleepIQ and updates the states."""
# Call the API for new sleepiq data. Each sensor will re-trigger this
# same exact call, but that's fine. We cache results for a short period
# of time to prevent hitting API limits.
self.sleepiq_data.update()
self.bed = self.sleepiq_data.beds[self._bed_id]
self.side = getattr(self.bed, self._side)