Skip to content
Snippets Groups Projects
Commit 9efa31ef authored by John Mihalic's avatar John Mihalic Committed by Paulus Schoutsen
Browse files

Eight Sleep add REM type, Update async syntax, Catch API quirks (#14937)

parent 8a777f6e
No related branches found
No related tags found
No related merge requests found
......@@ -5,7 +5,6 @@ For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/binary_sensor.eight_sleep/
"""
import logging
import asyncio
from homeassistant.components.binary_sensor import BinarySensorDevice
from homeassistant.components.eight_sleep import (
......@@ -16,8 +15,8 @@ _LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['eight_sleep']
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
async def async_setup_platform(hass, config, async_add_devices,
discovery_info=None):
"""Set up the eight sleep binary sensor."""
if discovery_info is None:
return
......@@ -63,7 +62,6 @@ class EightHeatSensor(EightSleepHeatEntity, BinarySensorDevice):
"""Return true if the binary sensor is on."""
return self._state
@asyncio.coroutine
def async_update(self):
async def async_update(self):
"""Retrieve latest state."""
self._state = self._usrobj.bed_presence
......@@ -4,7 +4,6 @@ Support for Eight smart mattress covers and mattresses.
For more details about this component, please refer to the documentation at
https://home-assistant.io/components/eight_sleep/
"""
import asyncio
import logging
from datetime import timedelta
......@@ -22,7 +21,7 @@ from homeassistant.helpers.entity import Entity
from homeassistant.helpers.event import async_track_point_in_utc_time
from homeassistant.util.dt import utcnow
REQUIREMENTS = ['pyeight==0.0.8']
REQUIREMENTS = ['pyeight==0.0.9']
_LOGGER = logging.getLogger(__name__)
......@@ -86,8 +85,7 @@ CONFIG_SCHEMA = vol.Schema({
}, extra=vol.ALLOW_EXTRA)
@asyncio.coroutine
def async_setup(hass, config):
async def async_setup(hass, config):
"""Set up the Eight Sleep component."""
from pyeight.eight import EightSleep
......@@ -107,31 +105,29 @@ def async_setup(hass, config):
hass.data[DATA_EIGHT] = eight
# Authenticate, build sensors
success = yield from eight.start()
success = await eight.start()
if not success:
# Authentication failed, cannot continue
return False
@asyncio.coroutine
def async_update_heat_data(now):
async def async_update_heat_data(now):
"""Update heat data from eight in HEAT_SCAN_INTERVAL."""
yield from eight.update_device_data()
await eight.update_device_data()
async_dispatcher_send(hass, SIGNAL_UPDATE_HEAT)
async_track_point_in_utc_time(
hass, async_update_heat_data, utcnow() + HEAT_SCAN_INTERVAL)
@asyncio.coroutine
def async_update_user_data(now):
async def async_update_user_data(now):
"""Update user data from eight in USER_SCAN_INTERVAL."""
yield from eight.update_user_data()
await eight.update_user_data()
async_dispatcher_send(hass, SIGNAL_UPDATE_USER)
async_track_point_in_utc_time(
hass, async_update_user_data, utcnow() + USER_SCAN_INTERVAL)
yield from async_update_heat_data(None)
yield from async_update_user_data(None)
await async_update_heat_data(None)
await async_update_user_data(None)
# Load sub components
sensors = []
......@@ -157,8 +153,7 @@ def async_setup(hass, config):
CONF_BINARY_SENSORS: binary_sensors,
}, config))
@asyncio.coroutine
def async_service_handler(service):
async def async_service_handler(service):
"""Handle eight sleep service calls."""
params = service.data.copy()
......@@ -170,7 +165,7 @@ def async_setup(hass, config):
side = sens.split('_')[1]
userid = eight.fetch_userid(side)
usrobj = eight.users[userid]
yield from usrobj.set_heating_level(target, duration)
await usrobj.set_heating_level(target, duration)
async_dispatcher_send(hass, SIGNAL_UPDATE_HEAT)
......@@ -179,10 +174,9 @@ def async_setup(hass, config):
DOMAIN, SERVICE_HEAT_SET, async_service_handler,
schema=SERVICE_EIGHT_SCHEMA)
@asyncio.coroutine
def stop_eight(event):
async def stop_eight(event):
"""Handle stopping eight api session."""
yield from eight.stop()
await eight.stop()
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, stop_eight)
......@@ -196,8 +190,7 @@ class EightSleepUserEntity(Entity):
"""Initialize the data object."""
self._eight = eight
@asyncio.coroutine
def async_added_to_hass(self):
async def async_added_to_hass(self):
"""Register update dispatcher."""
@callback
def async_eight_user_update():
......@@ -220,8 +213,7 @@ class EightSleepHeatEntity(Entity):
"""Initialize the data object."""
self._eight = eight
@asyncio.coroutine
def async_added_to_hass(self):
async def async_added_to_hass(self):
"""Register update dispatcher."""
@callback
def async_eight_heat_update():
......
......@@ -5,7 +5,6 @@ For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/sensor.eight_sleep/
"""
import logging
import asyncio
from homeassistant.components.eight_sleep import (
DATA_EIGHT, EightSleepHeatEntity, EightSleepUserEntity,
......@@ -24,20 +23,20 @@ ATTR_AVG_HEART_RATE = 'Average Heart Rate'
ATTR_SLEEP_DUR = 'Time Slept'
ATTR_LIGHT_PERC = 'Light Sleep %'
ATTR_DEEP_PERC = 'Deep Sleep %'
ATTR_REM_PERC = 'REM Sleep %'
ATTR_TNT = 'Tosses & Turns'
ATTR_SLEEP_STAGE = 'Sleep Stage'
ATTR_TARGET_HEAT = 'Target Heating Level'
ATTR_ACTIVE_HEAT = 'Heating Active'
ATTR_DURATION_HEAT = 'Heating Time Remaining'
ATTR_LAST_SEEN = 'Last In Bed'
ATTR_PROCESSING = 'Processing'
ATTR_SESSION_START = 'Session Start'
_LOGGER = logging.getLogger(__name__)
@asyncio.coroutine
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
async def async_setup_platform(hass, config, async_add_devices,
discovery_info=None):
"""Set up the eight sleep sensors."""
if discovery_info is None:
return
......@@ -98,8 +97,7 @@ class EightHeatSensor(EightSleepHeatEntity):
"""Return the unit the value is expressed in."""
return '%'
@asyncio.coroutine
def async_update(self):
async def async_update(self):
"""Retrieve latest state."""
_LOGGER.debug("Updating Heat sensor: %s", self._sensor)
self._state = self._usrobj.heating_level
......@@ -110,7 +108,6 @@ class EightHeatSensor(EightSleepHeatEntity):
state_attr = {ATTR_TARGET_HEAT: self._usrobj.target_heating_level}
state_attr[ATTR_ACTIVE_HEAT] = self._usrobj.now_heating
state_attr[ATTR_DURATION_HEAT] = self._usrobj.heating_remaining
state_attr[ATTR_LAST_SEEN] = self._usrobj.last_seen
return state_attr
......@@ -164,8 +161,7 @@ class EightUserSensor(EightSleepUserEntity):
if 'bed_temp' in self._sensor:
return 'mdi:thermometer'
@asyncio.coroutine
def async_update(self):
async def async_update(self):
"""Retrieve latest state."""
_LOGGER.debug("Updating User sensor: %s", self._sensor)
if 'current' in self._sensor:
......@@ -176,10 +172,13 @@ class EightUserSensor(EightSleepUserEntity):
self._attr = self._usrobj.last_values
elif 'bed_temp' in self._sensor:
temp = self._usrobj.current_values['bed_temp']
if self._units == 'si':
self._state = round(temp, 2)
else:
self._state = round((temp*1.8)+32, 2)
try:
if self._units == 'si':
self._state = round(temp, 2)
else:
self._state = round((temp*1.8)+32, 2)
except TypeError:
self._state = None
elif 'sleep_stage' in self._sensor:
self._state = self._usrobj.current_values['stage']
......@@ -208,12 +207,27 @@ class EightUserSensor(EightSleepUserEntity):
except ZeroDivisionError:
state_attr[ATTR_DEEP_PERC] = 0
if self._units == 'si':
room_temp = round(self._attr['room_temp'], 2)
bed_temp = round(self._attr['bed_temp'], 2)
else:
room_temp = round((self._attr['room_temp']*1.8)+32, 2)
bed_temp = round((self._attr['bed_temp']*1.8)+32, 2)
try:
state_attr[ATTR_REM_PERC] = round((
self._attr['breakdown']['rem'] / sleep_time) * 100, 2)
except ZeroDivisionError:
state_attr[ATTR_REM_PERC] = 0
try:
if self._units == 'si':
room_temp = round(self._attr['room_temp'], 2)
else:
room_temp = round((self._attr['room_temp']*1.8)+32, 2)
except TypeError:
room_temp = None
try:
if self._units == 'si':
bed_temp = round(self._attr['bed_temp'], 2)
else:
bed_temp = round((self._attr['bed_temp']*1.8)+32, 2)
except TypeError:
bed_temp = None
if 'current' in self._sensor_root:
state_attr[ATTR_RESP_RATE] = round(self._attr['resp_rate'], 2)
......@@ -255,15 +269,17 @@ class EightRoomSensor(EightSleepUserEntity):
"""Return the state of the sensor."""
return self._state
@asyncio.coroutine
def async_update(self):
async def async_update(self):
"""Retrieve latest state."""
_LOGGER.debug("Updating Room sensor: %s", self._sensor)
temp = self._eight.room_temperature()
if self._units == 'si':
self._state = round(temp, 2)
else:
self._state = round((temp*1.8)+32, 2)
try:
if self._units == 'si':
self._state = round(temp, 2)
else:
self._state = round((temp*1.8)+32, 2)
except TypeError:
self._state = None
@property
def unit_of_measurement(self):
......
......@@ -811,7 +811,7 @@ pyeconet==0.0.5
pyedimax==0.1
# homeassistant.components.eight_sleep
pyeight==0.0.8
pyeight==0.0.9
# homeassistant.components.media_player.emby
pyemby==1.5
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment