From 71fc79db0b58c0a6b4484e19b6ffc286e7ea3143 Mon Sep 17 00:00:00 2001 From: Matt Snyder Date: Sun, 13 Jan 2019 22:16:24 -0600 Subject: [PATCH 01/20] Initial commit of owlet component --- .../components/binary_sensor/owlet.py | 85 ++++++++++++ homeassistant/components/owlet.py | 90 ++++++++++++ homeassistant/components/sensor/owlet.py | 129 ++++++++++++++++++ 3 files changed, 304 insertions(+) create mode 100644 homeassistant/components/binary_sensor/owlet.py create mode 100644 homeassistant/components/owlet.py create mode 100644 homeassistant/components/sensor/owlet.py diff --git a/homeassistant/components/binary_sensor/owlet.py b/homeassistant/components/binary_sensor/owlet.py new file mode 100644 index 00000000000000..e4e9f74d423382 --- /dev/null +++ b/homeassistant/components/binary_sensor/owlet.py @@ -0,0 +1,85 @@ +""" +Support for Owlet binary sensors. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/binary_sensor.owlet/ +""" +from datetime import timedelta + +from homeassistant.components.binary_sensor import BinarySensorDevice +from homeassistant.components.owlet import DOMAIN +from homeassistant.util import dt as dt_util + +SCAN_INTERVAL = timedelta(seconds=15) + +BINARY_CONDITIONS = { + 'base_station_on': { + 'name': 'Base Station', + 'device_class': 'power' + }, + 'movement': { + 'name': 'Movement', + 'device_class': 'motion' + } +} + +DEPENDENCIES = ['owlet'] + + +def setup_platform(hass, config, add_entities, discovery_info=None): + """Setup owlet binary sensor.""" + device = hass.data[DOMAIN] + + entities = [] + for condition in BINARY_CONDITIONS: + if condition in device.monitor: + entities.append(OwletBinarySensor(device, condition)) + + add_entities(entities, True) + + +class OwletBinarySensor(BinarySensorDevice): + """Representation of owlet binary sensor.""" + + def __init__(self, device, condition): + """Init owlet binary sensor.""" + self._device = device + self._condition = condition + self._state = None + self._base_on = False + self._prop_expiration = None + self._is_charging = None + + @property + def name(self): + """Return sensor name.""" + return '{} {}'.format(self._device.name, + BINARY_CONDITIONS[self._condition]['name']) + + @property + def is_on(self): + """Return current state of sensor.""" + return self._state + + @property + def device_class(self): + """Return the device class.""" + return BINARY_CONDITIONS[self._condition]['device_class'] + + def update(self): + """Update state of sensor.""" + self._base_on = self._device.device.base_station_on + self._prop_expiration = self._device.device.prop_expire_time + self._is_charging = self._device.device.charge_status > 0 + + # handle expired values + if self._prop_expiration < dt_util.now().timestamp(): + self._state = False + return + + if self._condition == 'movement': + if not self._base_on or self._is_charging: + return False + + self._state = getattr(self._device.device, self._condition) + diff --git a/homeassistant/components/owlet.py b/homeassistant/components/owlet.py new file mode 100644 index 00000000000000..f0d05671bbf96e --- /dev/null +++ b/homeassistant/components/owlet.py @@ -0,0 +1,90 @@ +""" +A component to connect to Owlet baby monitor + +For more details about this component, please refer to the documentation at +https://home-assistant.io/components/owlet/ +""" +import logging + +import voluptuous as vol + +from homeassistant.const import (CONF_USERNAME, CONF_PASSWORD, CONF_NAME, + CONF_MONITORED_CONDITIONS) +import homeassistant.helpers.config_validation as cv + +REQUIREMENTS = ['pyowlet==1.0.2'] + +_LOGGER = logging.getLogger(__name__) + +DOMAIN = 'owlet' + +SENSOR_TYPES = [ + 'oxygen_level', + 'heart_rate', + 'base_station_on', + 'movement' +] + +CONFIG_SCHEMA = vol.Schema({ + DOMAIN: vol.Schema({ + vol.Required(CONF_USERNAME): cv.string, + vol.Required(CONF_PASSWORD): cv.string, + vol.Optional(CONF_NAME): cv.string, + vol.Optional(CONF_MONITORED_CONDITIONS, default=[]): + vol.All(cv.ensure_list, [vol.In(SENSOR_TYPES)]), + }), +}, extra=vol.ALLOW_EXTRA) + + +def setup(hass, config): + """Setup owlet component""" + from pyowlet.PyOwlet import PyOwlet + + username = config[DOMAIN].get(CONF_USERNAME) + password = config[DOMAIN].get(CONF_PASSWORD) + name = config[DOMAIN].get(CONF_NAME) + monitor = config[DOMAIN].get(CONF_MONITORED_CONDITIONS) + + device = PyOwlet(username, password) + + device.update_properties() + + if not name: + name = '{}\'s Owlet'.format(device.baby_name) + + # Monitor all conditions by default + if not monitor: + monitor = SENSOR_TYPES + + hass.data[DOMAIN] = OwletDevice(device, name, monitor) + + return True + + +class OwletDevice(): + """Configured Owlet device""" + + def __init__(self, device, name, monitor): + """Initialize device.""" + self._name = name + self._monitor = monitor + self._device = device + + @property + def name(self): + """Get the name of the device.""" + return self._name + + @property + def monitor(self): + """Get monitored conditions.""" + return self._monitor + + @property + def device(self): + """Get device.""" + return self._device + + + + diff --git a/homeassistant/components/sensor/owlet.py b/homeassistant/components/sensor/owlet.py new file mode 100644 index 00000000000000..bff7d0bcfa5849 --- /dev/null +++ b/homeassistant/components/sensor/owlet.py @@ -0,0 +1,129 @@ +""" +Support for Ecobee sensors. + +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/binary_sensor.ecobee/ +""" +from datetime import timedelta + +from homeassistant.components.binary_sensor import BinarySensorDevice +from homeassistant.components.owlet import DOMAIN +from homeassistant.util import dt as dt_util + +DEPENDENCIES = ['owlet'] + +SCAN_INTERVAL = timedelta(seconds=15) + +SENSOR_CONDITIONS = { + 'oxygen_level': { + 'name': 'Oxygen Level', + 'device_class': '' + }, + 'heart_rate': { + 'name': 'Heart Rate', + 'device_class': '' + } +} + + +def setup_platform(hass, config, add_entities, discovery_info=None): + """Setup owlet binary sensor.""" + device = hass.data[DOMAIN] + + entities = [] + for condition in SENSOR_CONDITIONS: + if condition in device.monitor: + entities.append(OwletSensor(device, condition)) + + add_entities(entities, True) + + +class OwletSensor(BinarySensorDevice): + """Representation of owlet binary sensor.""" + + def __init__(self, device, condition): + """Init owlet binary sensor.""" + self._device = device + self._condition = condition + self._state = None + self._prop_expiration = None + self._is_charging = None + self._battery_level = None + self._sock_off = None + self._sock_connection = None + self._movement = None + + @property + def name(self): + """Return sensor name.""" + return '{} {}'.format(self._device.name, + SENSOR_CONDITIONS[self._condition]['name']) + + @property + def state(self): + """Return current state of sensor.""" + return self._state + + @property + def device_class(self): + """Return the device class.""" + return SENSOR_CONDITIONS[self._condition]['device_class'] + + @property + def is_charging(self): + return self._is_charging + + @property + def battery_level(self): + return self._battery_level + + @property + def sock_off(self): + return self._sock_off + + @property + def sock_connection(self): + return self._sock_connection + + @property + def device_state_attributes(self): + """Provide attributes for display on device card.""" + attributes = { + 'battery_charging': self.is_charging, + 'battery_level': self.battery_level, + 'sock_off': self.sock_off, + 'sock_connection': self.sock_connection + } + + return attributes + + def update(self): + """Update state of sensor.""" + + self._is_charging = self._device.device.charge_status + self._battery_level = self._device.device.batt_level + self._sock_off = self._device.device.sock_off + self._sock_connection = self._device.device.sock_connection + self._movement = self._device.device.movement + self._prop_expiration = self._device.device.prop_expire_time + + value = getattr(self._device.device, self._condition) + + if self._condition == 'batt_level': + self._state = 100 if value > 100 else value + return + + if not self._device.device.base_station_on: + value = '-' + + elif self._device.device.charge_status > 0: + value = '-' + + # handle expired values + elif self._prop_expiration < dt_util.now().timestamp(): + value = '-' + + elif self._movement: + value = '-' + + self._state = value From df1b363f7d663e12dc7791132324b072ad085e72 Mon Sep 17 00:00:00 2001 From: Matt Snyder Date: Sat, 19 Jan 2019 21:32:39 -0600 Subject: [PATCH 02/20] Remove monitored conditions --- homeassistant/components/owlet.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/homeassistant/components/owlet.py b/homeassistant/components/owlet.py index f0d05671bbf96e..8a110b504a9387 100644 --- a/homeassistant/components/owlet.py +++ b/homeassistant/components/owlet.py @@ -30,8 +30,6 @@ vol.Required(CONF_USERNAME): cv.string, vol.Required(CONF_PASSWORD): cv.string, vol.Optional(CONF_NAME): cv.string, - vol.Optional(CONF_MONITORED_CONDITIONS, default=[]): - vol.All(cv.ensure_list, [vol.In(SENSOR_TYPES)]), }), }, extra=vol.ALLOW_EXTRA) @@ -43,7 +41,6 @@ def setup(hass, config): username = config[DOMAIN].get(CONF_USERNAME) password = config[DOMAIN].get(CONF_PASSWORD) name = config[DOMAIN].get(CONF_NAME) - monitor = config[DOMAIN].get(CONF_MONITORED_CONDITIONS) device = PyOwlet(username, password) @@ -52,11 +49,7 @@ def setup(hass, config): if not name: name = '{}\'s Owlet'.format(device.baby_name) - # Monitor all conditions by default - if not monitor: - monitor = SENSOR_TYPES - - hass.data[DOMAIN] = OwletDevice(device, name, monitor) + hass.data[DOMAIN] = OwletDevice(device, name, SENSOR_TYPES) return True From 4ddb0538fb22acaaa863238cd4728c36e7a76d48 Mon Sep 17 00:00:00 2001 From: Matt Snyder Date: Sat, 19 Jan 2019 21:55:46 -0600 Subject: [PATCH 03/20] Formatting --- homeassistant/components/binary_sensor/owlet.py | 1 - homeassistant/components/owlet.py | 4 ---- 2 files changed, 5 deletions(-) diff --git a/homeassistant/components/binary_sensor/owlet.py b/homeassistant/components/binary_sensor/owlet.py index e4e9f74d423382..fb7583da1f3822 100644 --- a/homeassistant/components/binary_sensor/owlet.py +++ b/homeassistant/components/binary_sensor/owlet.py @@ -82,4 +82,3 @@ def update(self): return False self._state = getattr(self._device.device, self._condition) - diff --git a/homeassistant/components/owlet.py b/homeassistant/components/owlet.py index 8a110b504a9387..f9ba4bd93be41b 100644 --- a/homeassistant/components/owlet.py +++ b/homeassistant/components/owlet.py @@ -77,7 +77,3 @@ def monitor(self): def device(self): """Get device.""" return self._device - - - - From a1452bb23aadddde9089f286921db38ad4a58b50 Mon Sep 17 00:00:00 2001 From: Matt Snyder Date: Sat, 19 Jan 2019 21:59:03 -0600 Subject: [PATCH 04/20] Update requirements file --- requirements_all.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/requirements_all.txt b/requirements_all.txt index b7f4a207296df0..7773f3bbbd13f8 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1188,6 +1188,9 @@ pyotgw==0.4b1 # homeassistant.components.sensor.otp pyotp==2.2.6 +# homeassistant.components.owlet +pyowlet==1.0.2 + # homeassistant.components.sensor.openweathermap # homeassistant.components.weather.openweathermap pyowm==2.10.0 From d59b95195ffadcdccf99b8ef2a31b2ff7016ce0a Mon Sep 17 00:00:00 2001 From: Matt Snyder Date: Sat, 19 Jan 2019 22:02:01 -0600 Subject: [PATCH 05/20] Remove unused import --- homeassistant/components/owlet.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/homeassistant/components/owlet.py b/homeassistant/components/owlet.py index f9ba4bd93be41b..a3b9a5fb76bf0c 100644 --- a/homeassistant/components/owlet.py +++ b/homeassistant/components/owlet.py @@ -8,8 +8,7 @@ import voluptuous as vol -from homeassistant.const import (CONF_USERNAME, CONF_PASSWORD, CONF_NAME, - CONF_MONITORED_CONDITIONS) +from homeassistant.const import (CONF_USERNAME, CONF_PASSWORD, CONF_NAME) import homeassistant.helpers.config_validation as cv REQUIREMENTS = ['pyowlet==1.0.2'] From 8a81a2959f14e8bd7b3ae3cf4635ac57da26a5b6 Mon Sep 17 00:00:00 2001 From: Matt Snyder Date: Sun, 20 Jan 2019 08:41:41 -0600 Subject: [PATCH 06/20] Update scan interval --- homeassistant/components/binary_sensor/owlet.py | 2 +- homeassistant/components/sensor/owlet.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/binary_sensor/owlet.py b/homeassistant/components/binary_sensor/owlet.py index fb7583da1f3822..420e9913dde8e1 100644 --- a/homeassistant/components/binary_sensor/owlet.py +++ b/homeassistant/components/binary_sensor/owlet.py @@ -10,7 +10,7 @@ from homeassistant.components.owlet import DOMAIN from homeassistant.util import dt as dt_util -SCAN_INTERVAL = timedelta(seconds=15) +SCAN_INTERVAL = timedelta(seconds=120) BINARY_CONDITIONS = { 'base_station_on': { diff --git a/homeassistant/components/sensor/owlet.py b/homeassistant/components/sensor/owlet.py index bff7d0bcfa5849..5ff14abca61575 100644 --- a/homeassistant/components/sensor/owlet.py +++ b/homeassistant/components/sensor/owlet.py @@ -12,7 +12,7 @@ DEPENDENCIES = ['owlet'] -SCAN_INTERVAL = timedelta(seconds=15) +SCAN_INTERVAL = timedelta(seconds=120) SENSOR_CONDITIONS = { 'oxygen_level': { From d2758652c7af0e6f054386b3cce08da2f9362c96 Mon Sep 17 00:00:00 2001 From: Matt Snyder Date: Sun, 20 Jan 2019 18:48:55 -0600 Subject: [PATCH 07/20] Correct documentation link and copy paste remnant --- homeassistant/components/sensor/owlet.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/sensor/owlet.py b/homeassistant/components/sensor/owlet.py index 5ff14abca61575..5a7fd6a1f934df 100644 --- a/homeassistant/components/sensor/owlet.py +++ b/homeassistant/components/sensor/owlet.py @@ -1,8 +1,8 @@ """ -Support for Ecobee sensors. +Support for Owlet sensors. For more details about this platform, please refer to the documentation at -https://home-assistant.io/components/binary_sensor.ecobee/ +https://home-assistant.io/components/binary_sensor.owlet/ """ from datetime import timedelta From b0e2c2332a6348184fe18caec0cf98d7469f8a45 Mon Sep 17 00:00:00 2001 From: Matt Snyder Date: Mon, 21 Jan 2019 09:05:53 -0600 Subject: [PATCH 08/20] Wording --- homeassistant/components/owlet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/owlet.py b/homeassistant/components/owlet.py index a3b9a5fb76bf0c..0111a717605de5 100644 --- a/homeassistant/components/owlet.py +++ b/homeassistant/components/owlet.py @@ -1,5 +1,5 @@ """ -A component to connect to Owlet baby monitor +Support for Owlet baby monitors For more details about this component, please refer to the documentation at https://home-assistant.io/components/owlet/ From 73cfc4f4de2598898c038612e87a3cd34d0069ca Mon Sep 17 00:00:00 2001 From: Matt Snyder Date: Mon, 21 Jan 2019 09:07:49 -0600 Subject: [PATCH 09/20] Missing docstrings --- homeassistant/components/sensor/owlet.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/homeassistant/components/sensor/owlet.py b/homeassistant/components/sensor/owlet.py index 5a7fd6a1f934df..dbd472f126dcd2 100644 --- a/homeassistant/components/sensor/owlet.py +++ b/homeassistant/components/sensor/owlet.py @@ -71,18 +71,22 @@ def device_class(self): @property def is_charging(self): + """Return device is_charging value""" return self._is_charging @property def battery_level(self): + """Return device battery_level value""" return self._battery_level @property def sock_off(self): + """Return device sock_off value""" return self._sock_off @property def sock_connection(self): + """Return device sock_connection value""" return self._sock_connection @property From 117780232fc229bb5d0fd9a3336513d35877ce33 Mon Sep 17 00:00:00 2001 From: Matt Snyder Date: Mon, 21 Jan 2019 09:08:53 -0600 Subject: [PATCH 10/20] Imperative mood. Punctuation --- homeassistant/components/binary_sensor/owlet.py | 2 +- homeassistant/components/owlet.py | 4 ++-- homeassistant/components/sensor/owlet.py | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/homeassistant/components/binary_sensor/owlet.py b/homeassistant/components/binary_sensor/owlet.py index 420e9913dde8e1..a221f29fadad1e 100644 --- a/homeassistant/components/binary_sensor/owlet.py +++ b/homeassistant/components/binary_sensor/owlet.py @@ -27,7 +27,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None): - """Setup owlet binary sensor.""" + """Set up owlet binary sensor.""" device = hass.data[DOMAIN] entities = [] diff --git a/homeassistant/components/owlet.py b/homeassistant/components/owlet.py index 0111a717605de5..a14eb416502607 100644 --- a/homeassistant/components/owlet.py +++ b/homeassistant/components/owlet.py @@ -34,7 +34,7 @@ def setup(hass, config): - """Setup owlet component""" + """Set up owlet component.""" from pyowlet.PyOwlet import PyOwlet username = config[DOMAIN].get(CONF_USERNAME) @@ -54,7 +54,7 @@ def setup(hass, config): class OwletDevice(): - """Configured Owlet device""" + """Configured Owlet device.""" def __init__(self, device, name, monitor): """Initialize device.""" diff --git a/homeassistant/components/sensor/owlet.py b/homeassistant/components/sensor/owlet.py index dbd472f126dcd2..2a4ac9bf6db95c 100644 --- a/homeassistant/components/sensor/owlet.py +++ b/homeassistant/components/sensor/owlet.py @@ -27,7 +27,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None): - """Setup owlet binary sensor.""" + """Set up owlet binary sensor.""" device = hass.data[DOMAIN] entities = [] @@ -71,22 +71,22 @@ def device_class(self): @property def is_charging(self): - """Return device is_charging value""" + """Return device is_charging value.""" return self._is_charging @property def battery_level(self): - """Return device battery_level value""" + """Return device battery_level value.""" return self._battery_level @property def sock_off(self): - """Return device sock_off value""" + """Return device sock_off value.""" return self._sock_off @property def sock_connection(self): - """Return device sock_connection value""" + """Return device sock_connection value.""" return self._sock_connection @property From 6c1272c725748a8d0d19544b80361dc878479da1 Mon Sep 17 00:00:00 2001 From: Matt Snyder Date: Mon, 21 Jan 2019 12:52:52 -0600 Subject: [PATCH 11/20] Requested changes. Doc string fixes. Correct OwletBinarySensor parent class. Import corrections. --- homeassistant/components/binary_sensor/owlet.py | 4 ++-- homeassistant/components/owlet.py | 2 +- homeassistant/components/sensor/owlet.py | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/homeassistant/components/binary_sensor/owlet.py b/homeassistant/components/binary_sensor/owlet.py index a221f29fadad1e..13daedf0a53980 100644 --- a/homeassistant/components/binary_sensor/owlet.py +++ b/homeassistant/components/binary_sensor/owlet.py @@ -7,7 +7,7 @@ from datetime import timedelta from homeassistant.components.binary_sensor import BinarySensorDevice -from homeassistant.components.owlet import DOMAIN +from homeassistant.components.owlet import DOMAIN as OWLET_DOMAIN from homeassistant.util import dt as dt_util SCAN_INTERVAL = timedelta(seconds=120) @@ -28,7 +28,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None): """Set up owlet binary sensor.""" - device = hass.data[DOMAIN] + device = hass.data[OWLET_DOMAIN] entities = [] for condition in BINARY_CONDITIONS: diff --git a/homeassistant/components/owlet.py b/homeassistant/components/owlet.py index a14eb416502607..dc3a5c61ae242b 100644 --- a/homeassistant/components/owlet.py +++ b/homeassistant/components/owlet.py @@ -54,7 +54,7 @@ def setup(hass, config): class OwletDevice(): - """Configured Owlet device.""" + """Represents a configured Owlet device.""" def __init__(self, device, name, monitor): """Initialize device.""" diff --git a/homeassistant/components/sensor/owlet.py b/homeassistant/components/sensor/owlet.py index 2a4ac9bf6db95c..71d3a009013218 100644 --- a/homeassistant/components/sensor/owlet.py +++ b/homeassistant/components/sensor/owlet.py @@ -6,8 +6,8 @@ """ from datetime import timedelta -from homeassistant.components.binary_sensor import BinarySensorDevice -from homeassistant.components.owlet import DOMAIN +from homeassistant.components.owlet import DOMAIN as OWLET_DOMAIN +from homeassistant.helpers.entity import Entity from homeassistant.util import dt as dt_util DEPENDENCIES = ['owlet'] @@ -28,7 +28,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None): """Set up owlet binary sensor.""" - device = hass.data[DOMAIN] + device = hass.data[OWLET_DOMAIN] entities = [] for condition in SENSOR_CONDITIONS: @@ -38,8 +38,8 @@ def setup_platform(hass, config, add_entities, discovery_info=None): add_entities(entities, True) -class OwletSensor(BinarySensorDevice): - """Representation of owlet binary sensor.""" +class OwletSensor(Entity): + """Representation of Owlet sensor.""" def __init__(self, device, condition): """Init owlet binary sensor.""" From 0bb5cae7567435835f73fb37f26643992c01c85f Mon Sep 17 00:00:00 2001 From: Matt Snyder Date: Tue, 5 Feb 2019 16:37:13 -0600 Subject: [PATCH 12/20] Lint --- homeassistant/components/owlet.py | 2 +- homeassistant/components/sensor/owlet.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/homeassistant/components/owlet.py b/homeassistant/components/owlet.py index dc3a5c61ae242b..da20e616444245 100644 --- a/homeassistant/components/owlet.py +++ b/homeassistant/components/owlet.py @@ -1,5 +1,5 @@ """ -Support for Owlet baby monitors +Support for Owlet baby monitors. For more details about this component, please refer to the documentation at https://home-assistant.io/components/owlet/ diff --git a/homeassistant/components/sensor/owlet.py b/homeassistant/components/sensor/owlet.py index 71d3a009013218..c121bc5ab70c4e 100644 --- a/homeassistant/components/sensor/owlet.py +++ b/homeassistant/components/sensor/owlet.py @@ -103,7 +103,6 @@ def device_state_attributes(self): def update(self): """Update state of sensor.""" - self._is_charging = self._device.device.charge_status self._battery_level = self._device.device.batt_level self._sock_off = self._device.device.sock_off From 0b2f7fbd42c9de29d777f1bcceb60ed9a7dd0880 Mon Sep 17 00:00:00 2001 From: Matt Snyder Date: Tue, 5 Feb 2019 23:07:35 -0600 Subject: [PATCH 13/20] Embed platforms into component --- homeassistant/components/{owlet.py => owlet/__init__.py} | 5 +++++ .../{binary_sensor/owlet.py => owlet/binary_sensor.py} | 2 -- .../components/{sensor/owlet.py => owlet/sensor.py} | 2 -- 3 files changed, 5 insertions(+), 4 deletions(-) rename homeassistant/components/{owlet.py => owlet/__init__.py} (90%) rename homeassistant/components/{binary_sensor/owlet.py => owlet/binary_sensor.py} (98%) rename homeassistant/components/{sensor/owlet.py => owlet/sensor.py} (99%) diff --git a/homeassistant/components/owlet.py b/homeassistant/components/owlet/__init__.py similarity index 90% rename from homeassistant/components/owlet.py rename to homeassistant/components/owlet/__init__.py index da20e616444245..f52a1424ea38a0 100644 --- a/homeassistant/components/owlet.py +++ b/homeassistant/components/owlet/__init__.py @@ -10,6 +10,8 @@ from homeassistant.const import (CONF_USERNAME, CONF_PASSWORD, CONF_NAME) import homeassistant.helpers.config_validation as cv +from homeassistant.helpers.discovery import load_platform + REQUIREMENTS = ['pyowlet==1.0.2'] @@ -50,6 +52,9 @@ def setup(hass, config): hass.data[DOMAIN] = OwletDevice(device, name, SENSOR_TYPES) + load_platform(hass, 'sensor', DOMAIN, None, config) + load_platform(hass, 'binary_sensor', DOMAIN, None, config) + return True diff --git a/homeassistant/components/binary_sensor/owlet.py b/homeassistant/components/owlet/binary_sensor.py similarity index 98% rename from homeassistant/components/binary_sensor/owlet.py rename to homeassistant/components/owlet/binary_sensor.py index 13daedf0a53980..45d33540abca86 100644 --- a/homeassistant/components/binary_sensor/owlet.py +++ b/homeassistant/components/owlet/binary_sensor.py @@ -23,8 +23,6 @@ } } -DEPENDENCIES = ['owlet'] - def setup_platform(hass, config, add_entities, discovery_info=None): """Set up owlet binary sensor.""" diff --git a/homeassistant/components/sensor/owlet.py b/homeassistant/components/owlet/sensor.py similarity index 99% rename from homeassistant/components/sensor/owlet.py rename to homeassistant/components/owlet/sensor.py index c121bc5ab70c4e..4bd019c60772b7 100644 --- a/homeassistant/components/sensor/owlet.py +++ b/homeassistant/components/owlet/sensor.py @@ -10,8 +10,6 @@ from homeassistant.helpers.entity import Entity from homeassistant.util import dt as dt_util -DEPENDENCIES = ['owlet'] - SCAN_INTERVAL = timedelta(seconds=120) SENSOR_CONDITIONS = { From e9781530507f1c8a6719cb2d690431aad1602846 Mon Sep 17 00:00:00 2001 From: Matt Snyder Date: Tue, 5 Feb 2019 23:15:05 -0600 Subject: [PATCH 14/20] Update coveragerc again. --- .coveragerc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.coveragerc b/.coveragerc index dec0594e7a387a..e152cabef2a380 100644 --- a/.coveragerc +++ b/.coveragerc @@ -376,6 +376,9 @@ omit = homeassistant/components/openuv/__init__.py homeassistant/components/openuv/binary_sensor.py homeassistant/components/openuv/sensor.py + homeassistant/components/owlet/__init__.py + homeassistant/components/owlet/binary_sensor.py + homeassistant/components/owlet/sensor.py homeassistant/components/pilight/* homeassistant/components/plum_lightpad/* homeassistant/components/point/* From 1c67d9da6f95804321d43a4dc55dccc3e771dec0 Mon Sep 17 00:00:00 2001 From: Matt Snyder Date: Thu, 14 Feb 2019 18:28:30 -0600 Subject: [PATCH 15/20] Requested changes. --- .coveragerc | 4 +- homeassistant/components/owlet/__init__.py | 39 ++++------- .../components/owlet/binary_sensor.py | 11 +-- homeassistant/components/owlet/const.py | 6 ++ homeassistant/components/owlet/sensor.py | 69 ++++++------------- 5 files changed, 45 insertions(+), 84 deletions(-) create mode 100644 homeassistant/components/owlet/const.py diff --git a/.coveragerc b/.coveragerc index e152cabef2a380..8b51a34df61347 100644 --- a/.coveragerc +++ b/.coveragerc @@ -376,9 +376,7 @@ omit = homeassistant/components/openuv/__init__.py homeassistant/components/openuv/binary_sensor.py homeassistant/components/openuv/sensor.py - homeassistant/components/owlet/__init__.py - homeassistant/components/owlet/binary_sensor.py - homeassistant/components/owlet/sensor.py + homeassistant/components/owlet/* homeassistant/components/pilight/* homeassistant/components/plum_lightpad/* homeassistant/components/point/* diff --git a/homeassistant/components/owlet/__init__.py b/homeassistant/components/owlet/__init__.py index f52a1424ea38a0..88ab0c1e2ef8ee 100644 --- a/homeassistant/components/owlet/__init__.py +++ b/homeassistant/components/owlet/__init__.py @@ -1,8 +1,5 @@ """ Support for Owlet baby monitors. - -For more details about this component, please refer to the documentation at -https://home-assistant.io/components/owlet/ """ import logging @@ -12,7 +9,6 @@ import homeassistant.helpers.config_validation as cv from homeassistant.helpers.discovery import load_platform - REQUIREMENTS = ['pyowlet==1.0.2'] _LOGGER = logging.getLogger(__name__) @@ -39,11 +35,15 @@ def setup(hass, config): """Set up owlet component.""" from pyowlet.PyOwlet import PyOwlet - username = config[DOMAIN].get(CONF_USERNAME) - password = config[DOMAIN].get(CONF_PASSWORD) + username = config[DOMAIN][CONF_USERNAME] + password = config[DOMAIN][CONF_PASSWORD] name = config[DOMAIN].get(CONF_NAME) - device = PyOwlet(username, password) + try: + device = PyOwlet(username, password) + except KeyError: + _LOGGER.error('Owlet authentication failed. Please verify your credentials are correct.') + return False device.update_properties() @@ -52,8 +52,8 @@ def setup(hass, config): hass.data[DOMAIN] = OwletDevice(device, name, SENSOR_TYPES) - load_platform(hass, 'sensor', DOMAIN, None, config) - load_platform(hass, 'binary_sensor', DOMAIN, None, config) + load_platform(hass, 'sensor', DOMAIN, {}, config) + load_platform(hass, 'binary_sensor', DOMAIN, {}, config) return True @@ -63,21 +63,6 @@ class OwletDevice(): def __init__(self, device, name, monitor): """Initialize device.""" - self._name = name - self._monitor = monitor - self._device = device - - @property - def name(self): - """Get the name of the device.""" - return self._name - - @property - def monitor(self): - """Get monitored conditions.""" - return self._monitor - - @property - def device(self): - """Get device.""" - return self._device + self.name = name + self.monitor = monitor + self.device = device diff --git a/homeassistant/components/owlet/binary_sensor.py b/homeassistant/components/owlet/binary_sensor.py index 45d33540abca86..95f0a013ce313a 100644 --- a/homeassistant/components/owlet/binary_sensor.py +++ b/homeassistant/components/owlet/binary_sensor.py @@ -1,11 +1,9 @@ """ Support for Owlet binary sensors. - -For more details about this platform, please refer to the documentation at -https://home-assistant.io/components/binary_sensor.owlet/ """ from datetime import timedelta +from .const import SENSOR_BASE_STATION, SENSOR_MOVEMENT from homeassistant.components.binary_sensor import BinarySensorDevice from homeassistant.components.owlet import DOMAIN as OWLET_DOMAIN from homeassistant.util import dt as dt_util @@ -13,11 +11,11 @@ SCAN_INTERVAL = timedelta(seconds=120) BINARY_CONDITIONS = { - 'base_station_on': { + SENSOR_BASE_STATION: { 'name': 'Base Station', 'device_class': 'power' }, - 'movement': { + SENSOR_MOVEMENT: { 'name': 'Movement', 'device_class': 'motion' } @@ -28,6 +26,9 @@ def setup_platform(hass, config, add_entities, discovery_info=None): """Set up owlet binary sensor.""" device = hass.data[OWLET_DOMAIN] + if discovery_info is None: + return + entities = [] for condition in BINARY_CONDITIONS: if condition in device.monitor: diff --git a/homeassistant/components/owlet/const.py b/homeassistant/components/owlet/const.py new file mode 100644 index 00000000000000..e98e3d007e04e6 --- /dev/null +++ b/homeassistant/components/owlet/const.py @@ -0,0 +1,6 @@ +"""Constants for Owlet component.""" +SENSOR_OXYGEN_LEVEL = 'oxygen_level' +SENSOR_HEART_RATE = 'heart_rate' + +SENSOR_BASE_STATION = 'base_station_on' +SENSOR_MOVEMENT = 'movement' \ No newline at end of file diff --git a/homeassistant/components/owlet/sensor.py b/homeassistant/components/owlet/sensor.py index 4bd019c60772b7..57294a56a86c33 100644 --- a/homeassistant/components/owlet/sensor.py +++ b/homeassistant/components/owlet/sensor.py @@ -1,11 +1,9 @@ """ Support for Owlet sensors. - -For more details about this platform, please refer to the documentation at -https://home-assistant.io/components/binary_sensor.owlet/ """ from datetime import timedelta +from .const import SENSOR_HEART_RATE, SENSOR_OXYGEN_LEVEL from homeassistant.components.owlet import DOMAIN as OWLET_DOMAIN from homeassistant.helpers.entity import Entity from homeassistant.util import dt as dt_util @@ -13,13 +11,13 @@ SCAN_INTERVAL = timedelta(seconds=120) SENSOR_CONDITIONS = { - 'oxygen_level': { + SENSOR_OXYGEN_LEVEL: { 'name': 'Oxygen Level', - 'device_class': '' + 'device_class': None }, - 'heart_rate': { + SENSOR_HEART_RATE: { 'name': 'Heart Rate', - 'device_class': '' + 'device_class': None } } @@ -45,10 +43,10 @@ def __init__(self, device, condition): self._condition = condition self._state = None self._prop_expiration = None - self._is_charging = None - self._battery_level = None - self._sock_off = None - self._sock_connection = None + self.is_charging = None + self.battery_level = None + self.sock_off = None + self.sock_connection = None self._movement = None @property @@ -67,29 +65,9 @@ def device_class(self): """Return the device class.""" return SENSOR_CONDITIONS[self._condition]['device_class'] - @property - def is_charging(self): - """Return device is_charging value.""" - return self._is_charging - - @property - def battery_level(self): - """Return device battery_level value.""" - return self._battery_level - - @property - def sock_off(self): - """Return device sock_off value.""" - return self._sock_off - - @property - def sock_connection(self): - """Return device sock_connection value.""" - return self._sock_connection - @property def device_state_attributes(self): - """Provide attributes for display on device card.""" + """Return state attributes.""" attributes = { 'battery_charging': self.is_charging, 'battery_level': self.battery_level, @@ -101,30 +79,23 @@ def device_state_attributes(self): def update(self): """Update state of sensor.""" - self._is_charging = self._device.device.charge_status - self._battery_level = self._device.device.batt_level - self._sock_off = self._device.device.sock_off - self._sock_connection = self._device.device.sock_connection + self.is_charging = self._device.device.charge_status + self.battery_level = self._device.device.batt_level + self.sock_off = self._device.device.sock_off + self.sock_connection = self._device.device.sock_connection self._movement = self._device.device.movement self._prop_expiration = self._device.device.prop_expire_time value = getattr(self._device.device, self._condition) if self._condition == 'batt_level': - self._state = 100 if value > 100 else value + self._state = min(100, value) return - if not self._device.device.base_station_on: - value = '-' - - elif self._device.device.charge_status > 0: - value = '-' - - # handle expired values - elif self._prop_expiration < dt_util.now().timestamp(): - value = '-' - - elif self._movement: - value = '-' + elif not self._device.device.base_station_on \ + or self._device.device.charge_status > 0 \ + or self._prop_expiration < dt_util.now().timestamp() \ + or self._movement: + value = None self._state = value From 1997993970bc738b27202ee258889c82e101c9e2 Mon Sep 17 00:00:00 2001 From: Matt Snyder Date: Thu, 14 Feb 2019 18:30:48 -0600 Subject: [PATCH 16/20] Please the hound --- homeassistant/components/owlet/__init__.py | 3 ++- homeassistant/components/owlet/const.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/owlet/__init__.py b/homeassistant/components/owlet/__init__.py index 88ab0c1e2ef8ee..081814ff54dc8f 100644 --- a/homeassistant/components/owlet/__init__.py +++ b/homeassistant/components/owlet/__init__.py @@ -42,7 +42,8 @@ def setup(hass, config): try: device = PyOwlet(username, password) except KeyError: - _LOGGER.error('Owlet authentication failed. Please verify your credentials are correct.') + _LOGGER.error('Owlet authentication failed. Please verify your ' + 'credentials are correct.') return False device.update_properties() diff --git a/homeassistant/components/owlet/const.py b/homeassistant/components/owlet/const.py index e98e3d007e04e6..f8d4db3ec1e191 100644 --- a/homeassistant/components/owlet/const.py +++ b/homeassistant/components/owlet/const.py @@ -3,4 +3,4 @@ SENSOR_HEART_RATE = 'heart_rate' SENSOR_BASE_STATION = 'base_station_on' -SENSOR_MOVEMENT = 'movement' \ No newline at end of file +SENSOR_MOVEMENT = 'movement' From 59b8b8e2f21247814880ae1c48f0c10bf21de0e0 Mon Sep 17 00:00:00 2001 From: Matt Snyder Date: Thu, 14 Feb 2019 18:41:32 -0600 Subject: [PATCH 17/20] Missed a change --- homeassistant/components/owlet/__init__.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/owlet/__init__.py b/homeassistant/components/owlet/__init__.py index 081814ff54dc8f..0ee5f11a890a37 100644 --- a/homeassistant/components/owlet/__init__.py +++ b/homeassistant/components/owlet/__init__.py @@ -5,6 +5,8 @@ import voluptuous as vol +from .const import SENSOR_MOVEMENT, SENSOR_BASE_STATION, SENSOR_HEART_RATE, \ + SENSOR_OXYGEN_LEVEL from homeassistant.const import (CONF_USERNAME, CONF_PASSWORD, CONF_NAME) import homeassistant.helpers.config_validation as cv from homeassistant.helpers.discovery import load_platform @@ -16,10 +18,10 @@ DOMAIN = 'owlet' SENSOR_TYPES = [ - 'oxygen_level', - 'heart_rate', - 'base_station_on', - 'movement' + SENSOR_OXYGEN_LEVEL, + SENSOR_HEART_RATE, + SENSOR_BASE_STATION, + SENSOR_MOVEMENT ] CONFIG_SCHEMA = vol.Schema({ From 3fc8df09148e89fac8f2096f67f44e6af990b05c Mon Sep 17 00:00:00 2001 From: Matt Snyder Date: Thu, 14 Feb 2019 19:01:53 -0600 Subject: [PATCH 18/20] Guard clause updates --- homeassistant/components/owlet/binary_sensor.py | 4 ++-- homeassistant/components/owlet/sensor.py | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/owlet/binary_sensor.py b/homeassistant/components/owlet/binary_sensor.py index 95f0a013ce313a..beaa7999c98051 100644 --- a/homeassistant/components/owlet/binary_sensor.py +++ b/homeassistant/components/owlet/binary_sensor.py @@ -24,11 +24,11 @@ def setup_platform(hass, config, add_entities, discovery_info=None): """Set up owlet binary sensor.""" - device = hass.data[OWLET_DOMAIN] - if discovery_info is None: return + device = hass.data[OWLET_DOMAIN] + entities = [] for condition in BINARY_CONDITIONS: if condition in device.monitor: diff --git a/homeassistant/components/owlet/sensor.py b/homeassistant/components/owlet/sensor.py index 57294a56a86c33..e9d21f47643bcd 100644 --- a/homeassistant/components/owlet/sensor.py +++ b/homeassistant/components/owlet/sensor.py @@ -24,6 +24,9 @@ def setup_platform(hass, config, add_entities, discovery_info=None): """Set up owlet binary sensor.""" + if discovery_info is None: + return + device = hass.data[OWLET_DOMAIN] entities = [] From 694930c334450088f62b364402760138d6f844d2 Mon Sep 17 00:00:00 2001 From: Matt Snyder Date: Fri, 15 Feb 2019 08:11:12 -0600 Subject: [PATCH 19/20] Correct import order --- homeassistant/components/owlet/__init__.py | 5 +++-- homeassistant/components/owlet/binary_sensor.py | 3 ++- homeassistant/components/owlet/sensor.py | 5 +++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/owlet/__init__.py b/homeassistant/components/owlet/__init__.py index 0ee5f11a890a37..03895973766d58 100644 --- a/homeassistant/components/owlet/__init__.py +++ b/homeassistant/components/owlet/__init__.py @@ -5,12 +5,13 @@ import voluptuous as vol -from .const import SENSOR_MOVEMENT, SENSOR_BASE_STATION, SENSOR_HEART_RATE, \ - SENSOR_OXYGEN_LEVEL from homeassistant.const import (CONF_USERNAME, CONF_PASSWORD, CONF_NAME) import homeassistant.helpers.config_validation as cv from homeassistant.helpers.discovery import load_platform +from .const import SENSOR_MOVEMENT, SENSOR_BASE_STATION, SENSOR_HEART_RATE, \ + SENSOR_OXYGEN_LEVEL + REQUIREMENTS = ['pyowlet==1.0.2'] _LOGGER = logging.getLogger(__name__) diff --git a/homeassistant/components/owlet/binary_sensor.py b/homeassistant/components/owlet/binary_sensor.py index beaa7999c98051..d5f7e276da7904 100644 --- a/homeassistant/components/owlet/binary_sensor.py +++ b/homeassistant/components/owlet/binary_sensor.py @@ -3,11 +3,12 @@ """ from datetime import timedelta -from .const import SENSOR_BASE_STATION, SENSOR_MOVEMENT from homeassistant.components.binary_sensor import BinarySensorDevice from homeassistant.components.owlet import DOMAIN as OWLET_DOMAIN from homeassistant.util import dt as dt_util +from .const import SENSOR_BASE_STATION, SENSOR_MOVEMENT + SCAN_INTERVAL = timedelta(seconds=120) BINARY_CONDITIONS = { diff --git a/homeassistant/components/owlet/sensor.py b/homeassistant/components/owlet/sensor.py index e9d21f47643bcd..dcfb60f9e01175 100644 --- a/homeassistant/components/owlet/sensor.py +++ b/homeassistant/components/owlet/sensor.py @@ -3,11 +3,12 @@ """ from datetime import timedelta -from .const import SENSOR_HEART_RATE, SENSOR_OXYGEN_LEVEL from homeassistant.components.owlet import DOMAIN as OWLET_DOMAIN from homeassistant.helpers.entity import Entity from homeassistant.util import dt as dt_util +from .const import SENSOR_HEART_RATE, SENSOR_OXYGEN_LEVEL + SCAN_INTERVAL = timedelta(seconds=120) SENSOR_CONDITIONS = { @@ -95,7 +96,7 @@ def update(self): self._state = min(100, value) return - elif not self._device.device.base_station_on \ + if not self._device.device.base_station_on \ or self._device.device.charge_status > 0 \ or self._prop_expiration < dt_util.now().timestamp() \ or self._movement: From b1c4f7d739c07008ed49a6ab117cefb1b350712c Mon Sep 17 00:00:00 2001 From: Matt Snyder Date: Fri, 15 Feb 2019 12:25:54 -0600 Subject: [PATCH 20/20] Lint --- homeassistant/components/owlet/__init__.py | 4 +--- homeassistant/components/owlet/binary_sensor.py | 4 +--- homeassistant/components/owlet/sensor.py | 4 +--- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/owlet/__init__.py b/homeassistant/components/owlet/__init__.py index 03895973766d58..c29f937183f6aa 100644 --- a/homeassistant/components/owlet/__init__.py +++ b/homeassistant/components/owlet/__init__.py @@ -1,6 +1,4 @@ -""" -Support for Owlet baby monitors. -""" +"""Support for Owlet baby monitors.""" import logging import voluptuous as vol diff --git a/homeassistant/components/owlet/binary_sensor.py b/homeassistant/components/owlet/binary_sensor.py index d5f7e276da7904..cb66278150aea7 100644 --- a/homeassistant/components/owlet/binary_sensor.py +++ b/homeassistant/components/owlet/binary_sensor.py @@ -1,6 +1,4 @@ -""" -Support for Owlet binary sensors. -""" +"""Support for Owlet binary sensors.""" from datetime import timedelta from homeassistant.components.binary_sensor import BinarySensorDevice diff --git a/homeassistant/components/owlet/sensor.py b/homeassistant/components/owlet/sensor.py index dcfb60f9e01175..b91cc387718646 100644 --- a/homeassistant/components/owlet/sensor.py +++ b/homeassistant/components/owlet/sensor.py @@ -1,6 +1,4 @@ -""" -Support for Owlet sensors. -""" +"""Support for Owlet sensors.""" from datetime import timedelta from homeassistant.components.owlet import DOMAIN as OWLET_DOMAIN