Nest fixes (#5011)

* Updated Nest API to have logical names

* Fix NoneType not having replace method in NestSensor constructor

* Move name setting to constructor, in case zone.name causes IO.

* normalize is_online to online

* Updated python-nest API

* push is_* helpers down to python-nest, and use inheritence to implement rather than checking class name

* Update python-nest
This commit is contained in:
Josh Nichols 2016-12-22 14:22:07 -05:00 committed by Pascal Vizeli
parent 5e1e5992af
commit 6c50f53696
6 changed files with 31 additions and 55 deletions

View file

@ -13,8 +13,7 @@ from homeassistant.components.binary_sensor import (
BinarySensorDevice, PLATFORM_SCHEMA) BinarySensorDevice, PLATFORM_SCHEMA)
from homeassistant.components.sensor.nest import NestSensor from homeassistant.components.sensor.nest import NestSensor
from homeassistant.const import (CONF_SCAN_INTERVAL, CONF_MONITORED_CONDITIONS) from homeassistant.const import (CONF_SCAN_INTERVAL, CONF_MONITORED_CONDITIONS)
from homeassistant.components.nest import ( from homeassistant.components.nest import DATA_NEST
DATA_NEST, is_thermostat, is_camera)
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
DEPENDENCIES = ['nest'] DEPENDENCIES = ['nest']
@ -76,9 +75,9 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
_LOGGER.error(wstr) _LOGGER.error(wstr)
sensors = [] sensors = []
device_chain = chain(nest.devices(), device_chain = chain(nest.thermostats(),
nest.protect_devices(), nest.smoke_co_alarms(),
nest.camera_devices()) nest.cameras())
for structure, device in device_chain: for structure, device in device_chain:
sensors += [NestBinarySensor(structure, device, variable) sensors += [NestBinarySensor(structure, device, variable)
for variable in conf for variable in conf
@ -86,9 +85,9 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
sensors += [NestBinarySensor(structure, device, variable) sensors += [NestBinarySensor(structure, device, variable)
for variable in conf for variable in conf
if variable in CLIMATE_BINARY_TYPES if variable in CLIMATE_BINARY_TYPES
and is_thermostat(device)] and device.is_thermostat]
if is_camera(device): if device.is_camera:
sensors += [NestBinarySensor(structure, device, variable) sensors += [NestBinarySensor(structure, device, variable)
for variable in conf for variable in conf
if variable in CAMERA_BINARY_TYPES] if variable in CAMERA_BINARY_TYPES]
@ -118,13 +117,14 @@ class NestActivityZoneSensor(NestBinarySensor):
def __init__(self, structure, device, zone): def __init__(self, structure, device, zone):
"""Initialize the sensor.""" """Initialize the sensor."""
super(NestActivityZoneSensor, self).__init__(structure, device, None) super(NestActivityZoneSensor, self).__init__(structure, device, "")
self.zone = zone self.zone = zone
self._name = "{} {} activity".format(self._name, self.zone.name)
@property @property
def name(self): def name(self):
"""Return the name of the nest, if any.""" """Return the name of the nest, if any."""
return "{} {} activity".format(self._name, self.zone.name) return self._name
def update(self): def update(self):
"""Retrieve latest state.""" """Retrieve latest state."""

View file

@ -27,7 +27,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
if discovery_info is None: if discovery_info is None:
return return
camera_devices = hass.data[nest.DATA_NEST].camera_devices() camera_devices = hass.data[nest.DATA_NEST].cameras()
cameras = [NestCamera(structure, device) cameras = [NestCamera(structure, device)
for structure, device in camera_devices] for structure, device in camera_devices]
add_devices(cameras, True) add_devices(cameras, True)
@ -43,7 +43,7 @@ class NestCamera(Camera):
self.device = device self.device = device
self._location = None self._location = None
self._name = None self._name = None
self._is_online = None self._online = None
self._is_streaming = None self._is_streaming = None
self._is_video_history_enabled = False self._is_video_history_enabled = False
# Default to non-NestAware subscribed, but will be fixed during update # Default to non-NestAware subscribed, but will be fixed during update
@ -76,7 +76,7 @@ class NestCamera(Camera):
"""Cache value from Python-nest.""" """Cache value from Python-nest."""
self._location = self.device.where self._location = self.device.where
self._name = self.device.name self._name = self.device.name
self._is_online = self.device.is_online self._online = self.device.online
self._is_streaming = self.device.is_streaming self._is_streaming = self.device.is_streaming
self._is_video_history_enabled = self.device.is_video_history_enabled self._is_video_history_enabled = self.device.is_video_history_enabled

View file

@ -40,7 +40,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
add_devices( add_devices(
[NestThermostat(structure, device, temp_unit) [NestThermostat(structure, device, temp_unit)
for structure, device in hass.data[DATA_NEST].devices()], for structure, device in hass.data[DATA_NEST].thermostats()],
True True
) )

View file

@ -19,8 +19,8 @@ _LOGGER = logging.getLogger(__name__)
REQUIREMENTS = [ REQUIREMENTS = [
'http://github.com/technicalpickles/python-nest' 'http://github.com/technicalpickles/python-nest'
'/archive/b8391d2b3cb8682f8b0c2bdff477179983609f39.zip' # nest-cam branch '/archive/e6c9d56a8df455d4d7746389811f2c1387e8cb33.zip' # nest-cam branch
'#python-nest==3.0.2'] '#python-nest==3.0.3']
DOMAIN = 'nest' DOMAIN = 'nest'
@ -132,12 +132,12 @@ class NestDevice(object):
self._structure = conf[CONF_STRUCTURE] self._structure = conf[CONF_STRUCTURE]
_LOGGER.debug("Structures to include: %s", self._structure) _LOGGER.debug("Structures to include: %s", self._structure)
def devices(self): def thermostats(self):
"""Generator returning list of devices and their location.""" """Generator returning list of thermostats and their location."""
try: try:
for structure in self.nest.structures: for structure in self.nest.structures:
if structure.name in self._structure: if structure.name in self._structure:
for device in structure.devices: for device in structure.thermostats:
yield (structure, device) yield (structure, device)
else: else:
_LOGGER.debug("Ignoring structure %s, not in %s", _LOGGER.debug("Ignoring structure %s, not in %s",
@ -146,12 +146,12 @@ class NestDevice(object):
_LOGGER.error( _LOGGER.error(
"Connection error logging into the nest web service.") "Connection error logging into the nest web service.")
def protect_devices(self): def smoke_co_alarms(self):
"""Generator returning list of protect devices.""" """Generator returning list of smoke co alarams."""
try: try:
for structure in self.nest.structures: for structure in self.nest.structures:
if structure.name in self._structure: if structure.name in self._structure:
for device in structure.protectdevices: for device in structure.smoke_co_alarms:
yield(structure, device) yield(structure, device)
else: else:
_LOGGER.info("Ignoring structure %s, not in %s", _LOGGER.info("Ignoring structure %s, not in %s",
@ -160,12 +160,12 @@ class NestDevice(object):
_LOGGER.error( _LOGGER.error(
"Connection error logging into the nest web service.") "Connection error logging into the nest web service.")
def camera_devices(self): def cameras(self):
"""Generator returning list of camera devices.""" """Generator returning list of cameras."""
try: try:
for structure in self.nest.structures: for structure in self.nest.structures:
if structure.name in self._structure: if structure.name in self._structure:
for device in structure.cameradevices: for device in structure.cameras:
yield(structure, device) yield(structure, device)
else: else:
_LOGGER.info("Ignoring structure %s, not in %s", _LOGGER.info("Ignoring structure %s, not in %s",
@ -173,18 +173,3 @@ class NestDevice(object):
except socket.error: except socket.error:
_LOGGER.error( _LOGGER.error(
"Connection error logging into the nest web service.") "Connection error logging into the nest web service.")
def is_thermostat(device):
"""Target devices that are Nest Thermostats."""
return bool(device.__class__.__name__ == 'Device')
def is_protect(device):
"""Target devices that are Nest Protect Smoke Alarms."""
return bool(device.__class__.__name__ == 'ProtectDevice')
def is_camera(device):
"""Target devices that are Nest Protect Smoke Alarms."""
return bool(device.__class__.__name__ == 'CameraDevice')

View file

@ -9,7 +9,8 @@ import logging
import voluptuous as vol import voluptuous as vol
from homeassistant.components.nest import DATA_NEST, DOMAIN from homeassistant.components.nest import (
DATA_NEST, DOMAIN)
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.const import ( from homeassistant.const import (
TEMP_CELSIUS, TEMP_FAHRENHEIT, CONF_PLATFORM, TEMP_CELSIUS, TEMP_FAHRENHEIT, CONF_PLATFORM,
@ -93,31 +94,21 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
_LOGGER.error(wstr) _LOGGER.error(wstr)
all_sensors = [] all_sensors = []
for structure, device in chain(nest.devices(), nest.protect_devices()): for structure, device in chain(nest.thermostats(), nest.smoke_co_alarms()):
sensors = [NestBasicSensor(structure, device, variable) sensors = [NestBasicSensor(structure, device, variable)
for variable in conf for variable in conf
if variable in SENSOR_TYPES and is_thermostat(device)] if variable in SENSOR_TYPES and device.is_thermostat]
sensors += [NestTempSensor(structure, device, variable) sensors += [NestTempSensor(structure, device, variable)
for variable in conf for variable in conf
if variable in SENSOR_TEMP_TYPES and is_thermostat(device)] if variable in SENSOR_TEMP_TYPES and device.is_thermostat]
sensors += [NestProtectSensor(structure, device, variable) sensors += [NestProtectSensor(structure, device, variable)
for variable in conf for variable in conf
if variable in PROTECT_VARS and is_protect(device)] if variable in PROTECT_VARS and device.is_smoke_co_alarm]
all_sensors.extend(sensors) all_sensors.extend(sensors)
add_devices(all_sensors, True) add_devices(all_sensors, True)
def is_thermostat(device):
"""Target devices that are Nest Thermostats."""
return bool(device.__class__.__name__ == 'Device')
def is_protect(device):
"""Target devices that are Nest Protect Smoke Alarms."""
return bool(device.__class__.__name__ == 'ProtectDevice')
class NestSensor(Entity): class NestSensor(Entity):
"""Representation of a Nest sensor.""" """Representation of a Nest sensor."""

View file

@ -175,7 +175,7 @@ hikvision==0.4
# http://github.com/adafruit/Adafruit_Python_DHT/archive/310c59b0293354d07d94375f1365f7b9b9110c7d.zip#Adafruit_DHT==1.3.0 # http://github.com/adafruit/Adafruit_Python_DHT/archive/310c59b0293354d07d94375f1365f7b9b9110c7d.zip#Adafruit_DHT==1.3.0
# homeassistant.components.nest # homeassistant.components.nest
http://github.com/technicalpickles/python-nest/archive/b8391d2b3cb8682f8b0c2bdff477179983609f39.zip#python-nest==3.0.2 http://github.com/technicalpickles/python-nest/archive/e6c9d56a8df455d4d7746389811f2c1387e8cb33.zip#python-nest==3.0.3
# homeassistant.components.light.flux_led # homeassistant.components.light.flux_led
https://github.com/Danielhiversen/flux_led/archive/0.10.zip#flux_led==0.10 https://github.com/Danielhiversen/flux_led/archive/0.10.zip#flux_led==0.10