Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sleepiq single sleeper crash #24941

Merged
merged 10 commits into from Jul 7, 2019
3 changes: 1 addition & 2 deletions homeassistant/components/sleepiq/__init__.py
@@ -1,7 +1,6 @@
"""Support for SleepIQ from SleepNumber."""
import logging
from datetime import timedelta
from requests.exceptions import HTTPError

import voluptuous as vol

Expand Down Expand Up @@ -53,7 +52,7 @@ def setup(hass, config):
try:
DATA = SleepIQData(client)
DATA.update()
except HTTPError:
except ValueError:
message = """
SleepIQ failed to login, double check your username and password"
"""
Expand Down
5 changes: 3 additions & 2 deletions homeassistant/components/sleepiq/binary_sensor.py
Expand Up @@ -12,9 +12,10 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
data.update()

dev = list()
for bed_id, _ in data.beds.items():
for bed_id, bed in data.beds.items():
for side in sleepiq.SIDES:
dev.append(IsInBedBinarySensor(data, bed_id, side))
if getattr(bed, side) is not None:
dev.append(IsInBedBinarySensor(data, bed_id, side))
add_entities(dev)


Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/sleepiq/manifest.json
Expand Up @@ -3,7 +3,7 @@
"name": "Sleepiq",
"documentation": "https://www.home-assistant.io/components/sleepiq",
"requirements": [
"sleepyq==0.6"
"sleepyq==0.7"
],
"dependencies": [],
"codeowners": []
Expand Down
5 changes: 3 additions & 2 deletions homeassistant/components/sleepiq/sensor.py
Expand Up @@ -13,9 +13,10 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
data.update()

dev = list()
for bed_id, _ in data.beds.items():
for bed_id, bed in data.beds.items():
for side in sleepiq.SIDES:
dev.append(SleepNumberSensor(data, bed_id, side))
if getattr(bed, side) is not None:
dev.append(SleepNumberSensor(data, bed_id, side))
add_entities(dev)


Expand Down
2 changes: 1 addition & 1 deletion requirements_all.txt
Expand Up @@ -1671,7 +1671,7 @@ skybellpy==0.4.0
slacker==0.13.0

# homeassistant.components.sleepiq
sleepyq==0.6
sleepyq==0.7

# homeassistant.components.xmpp
slixmpp==1.4.2
Expand Down
2 changes: 1 addition & 1 deletion requirements_test_all.txt
Expand Up @@ -332,7 +332,7 @@ rxv==0.6.0
simplisafe-python==3.4.2

# homeassistant.components.sleepiq
sleepyq==0.6
sleepyq==0.7

# homeassistant.components.smhi
smhi-pkg==1.0.10
Expand Down
19 changes: 19 additions & 0 deletions tests/components/sleepiq/test_binary_sensor.py
Expand Up @@ -30,6 +30,7 @@ def setUp(self):
'username': self.username,
'password': self.password,
}
self.DEVICES = []

def tearDown(self): # pylint: disable=invalid-name
"""Stop everything that was started."""
Expand All @@ -56,3 +57,21 @@ def test_setup(self, mock):
right_side = self.DEVICES[0]
assert 'SleepNumber ILE Test2 Is In Bed' == right_side.name
assert 'off' == right_side.state

@requests_mock.Mocker()
def test_setup_single(self, mock):
"""Test for successfully setting up the SleepIQ platform."""
mock_responses(mock, single=True)

setup_component(self.hass, 'sleepiq', {
'sleepiq': self.config})

sleepiq.setup_platform(self.hass,
self.config,
self.add_entities,
MagicMock())
assert 1 == len(self.DEVICES)

right_side = self.DEVICES[0]
assert 'SleepNumber ILE Test1 Is In Bed' == right_side.name
assert 'on' == right_side.state
14 changes: 9 additions & 5 deletions tests/components/sleepiq/test_init.py
Expand Up @@ -10,21 +10,25 @@
from tests.common import load_fixture, get_test_home_assistant


def mock_responses(mock):
def mock_responses(mock, single=False):
"""Mock responses for SleepIQ."""
base_url = 'https://api.sleepiq.sleepnumber.com/rest/'
base_url = 'https://prod-api.sleepiq.sleepnumber.com/rest/'
if single:
suffix = '-single'
else:
suffix = ''
mock.put(
base_url + 'login',
text=load_fixture('sleepiq-login.json'))
mock.get(
base_url + 'bed?_k=0987',
text=load_fixture('sleepiq-bed.json'))
text=load_fixture('sleepiq-bed{}.json'.format(suffix)))
mock.get(
base_url + 'sleeper?_k=0987',
text=load_fixture('sleepiq-sleeper.json'))
mock.get(
base_url + 'bed/familyStatus?_k=0987',
text=load_fixture('sleepiq-familystatus.json'))
text=load_fixture('sleepiq-familystatus{}.json'.format(suffix)))


class TestSleepIQ(unittest.TestCase):
Expand Down Expand Up @@ -61,7 +65,7 @@ def test_setup(self, mock):
@requests_mock.Mocker()
def test_setup_login_failed(self, mock):
"""Test the setup if a bad username or password is given."""
mock.put('https://api.sleepiq.sleepnumber.com/rest/login',
mock.put('https://prod-api.sleepiq.sleepnumber.com/rest/login',
status_code=401,
json=load_fixture('sleepiq-login-failed.json'))

Expand Down
25 changes: 21 additions & 4 deletions tests/components/sleepiq/test_sensor.py
Expand Up @@ -30,6 +30,7 @@ def setUp(self):
'username': self.username,
'password': self.password,
}
self.DEVICES = []

def tearDown(self): # pylint: disable=invalid-name
"""Stop everything that was started."""
Expand All @@ -41,10 +42,7 @@ def test_setup(self, mock):
mock_responses(mock)

assert setup_component(self.hass, 'sleepiq', {
'sleepiq': {
'username': '',
'password': '',
}
'sleepiq': self.config
})

sleepiq.setup_platform(self.hass,
Expand All @@ -60,3 +58,22 @@ def test_setup(self, mock):
right_side = self.DEVICES[0]
assert 'SleepNumber ILE Test2 SleepNumber' == right_side.name
assert 80 == right_side.state

@requests_mock.Mocker()
def test_setup_sigle(self, mock):
"""Test for successfully setting up the SleepIQ platform."""
mock_responses(mock, single=True)

assert setup_component(self.hass, 'sleepiq', {
'sleepiq': self.config
})

sleepiq.setup_platform(self.hass,
self.config,
self.add_entities,
MagicMock())
assert 1 == len(self.DEVICES)

right_side = self.DEVICES[0]
assert 'SleepNumber ILE Test1 SleepNumber' == right_side.name
assert 40 == right_side.state
27 changes: 27 additions & 0 deletions tests/fixtures/sleepiq-bed-single.json
@@ -0,0 +1,27 @@
{
"beds" : [
{
"dualSleep" : false,
"base" : "FlexFit",
"sku" : "AILE",
"model" : "ILE",
"size" : "KING",
"isKidsBed" : false,
"sleeperRightId" : "-80",
"accountId" : "-32",
"bedId" : "-31",
"registrationDate" : "2016-07-22T14:00:58Z",
"serial" : null,
"reference" : "95000794555-1",
"macAddress" : "CD13A384BA51",
"version" : null,
"purchaseDate" : "2016-06-22T00:00:00Z",
"sleeperLeftId" : "0",
"zipcode" : "12345",
"returnRequestStatus" : 0,
"name" : "ILE",
"status" : 1,
"timezone" : "US/Eastern"
}
]
}
17 changes: 17 additions & 0 deletions tests/fixtures/sleepiq-familystatus-single.json
@@ -0,0 +1,17 @@
{
"beds" : [
{
"bedId" : "-31",
"rightSide" : {
"alertId" : 0,
"lastLink" : "00:00:00",
"isInBed" : true,
"sleepNumber" : 40,
"alertDetailedMessage" : "No Alert",
"pressure" : -16
},
"status" : 1,
"leftSide" : null
}
]
}