Created
August 19, 2016 21:57
-
-
Save technicalpickles/e642164926f4259aa029409f59b0baa3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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