Skip to content

Instantly share code, notes, and snippets.

@technicalpickles
Created August 19, 2016 21:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save technicalpickles/e642164926f4259aa029409f59b0baa3 to your computer and use it in GitHub Desktop.
Save technicalpickles/e642164926f4259aa029409f59b0baa3 to your computer and use it in GitHub Desktop.
import logging
from datetime import timedelta
from requests.exceptions import ConnectionError as ConnectError, \
HTTPError, Timeout
from homeassistant.components.sensor import DOMAIN
from homeassistant.helpers import validate_config
from homeassistant.helpers.entity import Entity
from homeassistant.util import Throttle
from pprint import pprint
from sleepyq import Sleepyq
REQUIREMENTS = ['sleepyq==0.2']
# Return cached results if last scan was less then this time ago.
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=30)
SENSOR_TYPES = {
'sleep_number': 'SleepNumber',
'is_in_bed': 'Is In Bed',
}
ICON = 'mdi:hotel'
class SleepIQData(object):
"""Gets the latest data from SleepIQ."""
def __init__(self, login, password):
"""Initialize the data object."""
self._client = Sleepyq(login, password)
self.beds = None
self.sleepers = None
self.statuses = None
self.update()
@Throttle(MIN_TIME_BETWEEN_UPDATES)
def update(self):
"""Get the latest data from SleepIQ."""
self._client.login()
beds = self._client.beds()
sleepers = self._client.sleepers()
family_statuses = self._client.bed_family_status()
sleepers_by_id = {sleeper['sleeperId']: sleeper for sleeper in sleepers}
bed_family_statuses_by_bed_id = {family_status['bedId']: family_status for family_status in family_statuses}
# FIXME handle 0 and > 1 bed
bed = beds[0]
self.bed_name = bed['name']
family_status = bed_family_statuses_by_bed_id[bed['bedId']]
left_sleeper = sleepers_by_id[bed['sleeperLeftId']]
left_status = family_status['leftSide']
right_sleeper = sleepers_by_id[bed['sleeperRightId']]
right_status = family_status['rightSide']
self.left = {
'sleeper': left_sleeper['firstName'],
'is_in_bed': left_status['isInBed'],
'sleep_number': left_status['sleepNumber'],
}
self.right = {
'sleeper': right_sleeper['firstName'],
'is_in_bed': right_status['isInBed'],
'sleep_number': right_status['sleepNumber'],
}
# pylint: disable=too-few-public-methods
class SleepIQSensor(Entity):
"""Implementation of a SleepIQ sensor."""
def __init__(self, sleepiq_data, bed_name, side, sensor_type):
"""Initialize the sensor."""
self.client_name = 'SleepNumber'
self._bed_name = bed_name
self._side = side
self._name = SENSOR_TYPES[sensor_type]
self.sleepiq_data = sleepiq_data
self.type = sensor_type
self._state = None
if self.type == 'sleep_number':
self._icon = 'mdi:hotel'
elif self.type == 'is_in_bed':
self._icon = 'mdi:sleep'
self.update()
@property
def name(self):
"""Return the name of the sensor."""
return '{} {} {} {}'.format(self.client_name, self._bed_name, self._sleeper, self._name)
@property
def state(self):
"""Return the state of the sensor."""
return self._state
@property
def icon(self):
"""Icon to use in the frontend, if any."""
return ICON
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 thats fine. We cache results for a short period
# of time to prevent hitting API limits.
self.sleepiq_data.update()
if self._side == 'right':
status = self.sleepiq_data.right
else:
status = self.sleepiq_data.left
self._sleeper = status['sleeper']
if self.type == 'sleep_number':
self._state = status['sleep_number']
elif self.type == 'is_in_bed':
self._state = status['is_in_bed']
def setup_platform(hass, config, add_devices, discovery_info=None):
sleepiq_data = SleepIQData(config['login'], config['password'])
sleepiq_data.update()
# Initialize and add all of the sensors.
sensors = []
sensors.append(SleepIQSensor(sleepiq_data, sleepiq_data.bed_name, 'left', 'sleep_number'))
sensors.append(SleepIQSensor(sleepiq_data, sleepiq_data.bed_name, 'left', 'is_in_bed'))
sensors.append(SleepIQSensor(sleepiq_data, sleepiq_data.bed_name, 'right', 'sleep_number'))
sensors.append(SleepIQSensor(sleepiq_data, sleepiq_data.bed_name, 'right', 'is_in_bed'))
add_devices(sensors)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment