Add Nest away binary sensor and eta sensor (#14406)

This commit is contained in:
Jason Hu 2018-05-23 12:40:33 -07:00 committed by Sebastian Muszynski
parent c13ebacce1
commit 3498234448
3 changed files with 65 additions and 17 deletions

View File

@ -29,6 +29,16 @@ CAMERA_BINARY_TYPES = [
'person_detected', 'person_detected',
] ]
STRUCTURE_BINARY_TYPES = [
'away',
# 'security_state', # wait for pending python-nest update
]
STRUCTURE_BINARY_STATE_MAP = {
'away': {'away': True, 'home': False},
'security_state': {'deter': True, 'ok': False},
}
_BINARY_TYPES_DEPRECATED = [ _BINARY_TYPES_DEPRECATED = [
'hvac_ac_state', 'hvac_ac_state',
'hvac_aux_heater_state', 'hvac_aux_heater_state',
@ -41,7 +51,7 @@ _BINARY_TYPES_DEPRECATED = [
] ]
_VALID_BINARY_SENSOR_TYPES = BINARY_TYPES + CLIMATE_BINARY_TYPES \ _VALID_BINARY_SENSOR_TYPES = BINARY_TYPES + CLIMATE_BINARY_TYPES \
+ CAMERA_BINARY_TYPES + CAMERA_BINARY_TYPES + STRUCTURE_BINARY_TYPES
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -68,6 +78,10 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
_LOGGER.error(wstr) _LOGGER.error(wstr)
sensors = [] sensors = []
for structure in nest.structures():
sensors += [NestBinarySensor(structure, None, variable)
for variable in conditions
if variable in STRUCTURE_BINARY_TYPES]
device_chain = chain(nest.thermostats(), device_chain = chain(nest.thermostats(),
nest.smoke_co_alarms(), nest.smoke_co_alarms(),
nest.cameras()) nest.cameras())
@ -88,7 +102,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
sensors += [NestActivityZoneSensor(structure, sensors += [NestActivityZoneSensor(structure,
device, device,
activity_zone)] activity_zone)]
add_devices(sensors, True) add_devices(sensors, True)
@ -102,7 +115,12 @@ class NestBinarySensor(NestSensor, BinarySensorDevice):
def update(self): def update(self):
"""Retrieve latest state.""" """Retrieve latest state."""
self._state = bool(getattr(self.device, self.variable)) value = getattr(self.device, self.variable)
if self.variable in STRUCTURE_BINARY_TYPES:
self._state = bool(STRUCTURE_BINARY_STATE_MAP
[self.variable][value])
else:
self._state = bool(value)
class NestActivityZoneSensor(NestBinarySensor): class NestActivityZoneSensor(NestBinarySensor):

View File

@ -168,6 +168,19 @@ class NestDevice(object):
self.local_structure = conf[CONF_STRUCTURE] self.local_structure = conf[CONF_STRUCTURE]
_LOGGER.debug("Structures to include: %s", self.local_structure) _LOGGER.debug("Structures to include: %s", self.local_structure)
def structures(self):
"""Generate a list of structures."""
try:
for structure in self.nest.structures:
if structure.name in self.local_structure:
yield structure
else:
_LOGGER.debug("Ignoring structure %s, not in %s",
structure.name, self.local_structure)
except socket.error:
_LOGGER.error(
"Connection error logging into the nest web service.")
def thermostats(self): def thermostats(self):
"""Generate a list of thermostats and their location.""" """Generate a list of thermostats and their location."""
try: try:
@ -188,10 +201,10 @@ class NestDevice(object):
for structure in self.nest.structures: for structure in self.nest.structures:
if structure.name in self.local_structure: if structure.name in self.local_structure:
for device in structure.smoke_co_alarms: for device in structure.smoke_co_alarms:
yield(structure, device) yield (structure, device)
else: else:
_LOGGER.info("Ignoring structure %s, not in %s", _LOGGER.debug("Ignoring structure %s, not in %s",
structure.name, self.local_structure) structure.name, self.local_structure)
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.")
@ -202,10 +215,10 @@ class NestDevice(object):
for structure in self.nest.structures: for structure in self.nest.structures:
if structure.name in self.local_structure: if structure.name in self.local_structure:
for device in structure.cameras: for device in structure.cameras:
yield(structure, device) yield (structure, device)
else: else:
_LOGGER.info("Ignoring structure %s, not in %s", _LOGGER.debug("Ignoring structure %s, not in %s",
structure.name, self.local_structure) structure.name, self.local_structure)
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.")

View File

@ -36,10 +36,15 @@ PROTECT_VARS_DEPRECATED = ['battery_level']
SENSOR_TEMP_TYPES = ['temperature', 'target'] SENSOR_TEMP_TYPES = ['temperature', 'target']
STRUCTURE_SENSOR_TYPES = ['eta']
VARIABLE_NAME_MAPPING = {'eta': 'eta_begin', 'operation_mode': 'mode'}
_SENSOR_TYPES_DEPRECATED = SENSOR_TYPES_DEPRECATED \ _SENSOR_TYPES_DEPRECATED = SENSOR_TYPES_DEPRECATED \
+ list(DEPRECATED_WEATHER_VARS.keys()) + PROTECT_VARS_DEPRECATED + list(DEPRECATED_WEATHER_VARS.keys()) + PROTECT_VARS_DEPRECATED
_VALID_SENSOR_TYPES = SENSOR_TYPES + SENSOR_TEMP_TYPES + PROTECT_VARS _VALID_SENSOR_TYPES = SENSOR_TYPES + SENSOR_TEMP_TYPES + PROTECT_VARS \
+ STRUCTURE_SENSOR_TYPES
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -73,6 +78,10 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
_LOGGER.error(wstr) _LOGGER.error(wstr)
all_sensors = [] all_sensors = []
for structure in nest.structures():
all_sensors += [NestBasicSensor(structure, None, variable)
for variable in conditions
if variable in STRUCTURE_SENSOR_TYPES]
for structure, device in chain(nest.thermostats(), nest.smoke_co_alarms()): for structure, device in chain(nest.thermostats(), nest.smoke_co_alarms()):
sensors = [NestBasicSensor(structure, device, variable) sensors = [NestBasicSensor(structure, device, variable)
for variable in conditions for variable in conditions
@ -94,13 +103,20 @@ class NestSensor(Entity):
def __init__(self, structure, device, variable): def __init__(self, structure, device, variable):
"""Initialize the sensor.""" """Initialize the sensor."""
self.structure = structure self.structure = structure
self.device = device
self.variable = variable self.variable = variable
# device specific if device is not None:
self._location = self.device.where # device specific
self._name = "{} {}".format(self.device.name_long, self.device = device
self.variable.replace("_", " ")) self._location = self.device.where
self._name = "{} {}".format(self.device.name_long,
self.variable.replace('_', ' '))
else:
# structure only
self.device = structure
self._name = "{} {}".format(self.structure.name,
self.variable.replace('_', ' '))
self._state = None self._state = None
self._unit = None self._unit = None
@ -127,8 +143,9 @@ class NestBasicSensor(NestSensor):
"""Retrieve latest state.""" """Retrieve latest state."""
self._unit = SENSOR_UNITS.get(self.variable, None) self._unit = SENSOR_UNITS.get(self.variable, None)
if self.variable == 'operation_mode': if self.variable in VARIABLE_NAME_MAPPING:
self._state = getattr(self.device, "mode") self._state = getattr(self.device,
VARIABLE_NAME_MAPPING[self.variable])
else: else:
self._state = getattr(self.device, self.variable) self._state = getattr(self.device, self.variable)