From 1a422ecd5a5b113cddeabd1381758f20e7bc5f96 Mon Sep 17 00:00:00 2001 From: Stefan Jonasson Date: Tue, 26 Jan 2016 22:11:27 +0100 Subject: [PATCH] Moved common z-wave node functionality to a common z-wave class --- homeassistant/components/light/zwave.py | 46 +++-------------- homeassistant/components/sensor/zwave.py | 65 +++--------------------- homeassistant/components/switch/zwave.py | 46 +++-------------- homeassistant/components/zwave.py | 65 +++++++++++++++++++++++- 4 files changed, 84 insertions(+), 138 deletions(-) diff --git a/homeassistant/components/light/zwave.py b/homeassistant/components/light/zwave.py index 07dbd0f26fc..aa686701cf3 100644 --- a/homeassistant/components/light/zwave.py +++ b/homeassistant/components/light/zwave.py @@ -12,9 +12,11 @@ from threading import Timer from homeassistant.const import STATE_ON, STATE_OFF from homeassistant.components.light import (Light, ATTR_BRIGHTNESS) -from homeassistant.util import slugify +from homeassistant.components.zwave import ZWaveDeviceEntity import homeassistant.components.zwave as zwave +DOMAIN = "light" + def setup_platform(hass, config, add_devices, discovery_info=None): """ Find and add Z-Wave lights. """ @@ -46,15 +48,14 @@ def brightness_state(value): return 255, STATE_OFF -class ZwaveDimmer(Light): +class ZwaveDimmer(ZWaveDeviceEntity, Light): """ Provides a Z-Wave dimmer. """ # pylint: disable=too-many-arguments def __init__(self, value): from openzwave.network import ZWaveNetwork from pydispatch import dispatcher - self._value = value - self._node = value.node + ZWaveDeviceEntity.__init__(self, value, DOMAIN) self._brightness, self._state = brightness_state(value) @@ -87,39 +88,6 @@ class ZwaveDimmer(Light): self.update_ha_state() - @property - def should_poll(self): - """ No polling needed for a light. """ - return False - - @property - def unique_id(self): - """ Returns a unique id. """ - return "ZWAVE-{}-{}".format(self._node.node_id, self._value.object_id) - - @property - def name(self): - """ Returns the name of the device. """ - name = self._node.name or "{} {}".format( - self._node.manufacturer_name, self._node.product_name) - - return "{} {}".format(name, self._value.label) - - @property - def entity_id(self): - """ Returns the entity_id of the device if any. - The entity_id contains node_id and value instance id - to not collide with other entity_ids""" - - entity_id = "light.{}_{}".format(slugify(self.name), - self._node.node_id) - - # Add the instance id if there is more than one instance for the value - if self._value.instance > 1: - return "{}_{}".format(entity_id, self._value.instance) - - return entity_id - @property def brightness(self): """ Brightness of this light between 0..255. """ @@ -140,10 +108,10 @@ class ZwaveDimmer(Light): # brightness. brightness = (self._brightness / 255) * 99 - if self._node.set_dimmer(self._value.value_id, brightness): + if self._value.node.set_dimmer(self._value.value_id, brightness): self._state = STATE_ON def turn_off(self, **kwargs): """ Turn the device off. """ - if self._node.set_dimmer(self._value.value_id, 0): + if self._value.node.set_dimmer(self._value.value_id, 0): self._state = STATE_OFF diff --git a/homeassistant/components/sensor/zwave.py b/homeassistant/components/sensor/zwave.py index e6f41b6fede..4c8ffb667c2 100644 --- a/homeassistant/components/sensor/zwave.py +++ b/homeassistant/components/sensor/zwave.py @@ -13,11 +13,13 @@ import datetime from homeassistant.helpers.event import track_point_in_time import homeassistant.util.dt as dt_util import homeassistant.components.zwave as zwave +from homeassistant.components.zwave import ZWaveDeviceEntity from homeassistant.helpers.entity import Entity -from homeassistant.util import slugify + from homeassistant.const import ( - ATTR_BATTERY_LEVEL, STATE_ON, STATE_OFF, - TEMP_CELCIUS, TEMP_FAHRENHEIT, ATTR_LOCATION) + STATE_ON, STATE_OFF, TEMP_CELCIUS, TEMP_FAHRENHEIT) + +DOMAIN = "sensor" PHILIO = '013c' PHILIO_SLIM_SENSOR = '0002' @@ -79,76 +81,23 @@ def setup_platform(hass, config, add_devices, discovery_info=None): add_devices([ZWaveAlarmSensor(value)]) -class ZWaveSensor(Entity): +class ZWaveSensor(ZWaveDeviceEntity, Entity): """ Represents a Z-Wave sensor. """ def __init__(self, sensor_value): from openzwave.network import ZWaveNetwork from pydispatch import dispatcher - self._value = sensor_value - self._node = sensor_value.node + ZWaveDeviceEntity.__init__(self, sensor_value, DOMAIN) dispatcher.connect( self.value_changed, ZWaveNetwork.SIGNAL_VALUE_CHANGED) - @property - def should_poll(self): - """ False because we will push our own state to HA when changed. """ - return False - - @property - def unique_id(self): - """ Returns a unique id. """ - return "ZWAVE-{}-{}".format(self._node.node_id, self._value.object_id) - - @property - def name(self): - """ Returns the name of the device. """ - name = self._node.name or "{} {}".format( - self._node.manufacturer_name, self._node.product_name) - - return "{} {} {}".format(name, self._node.node_id, self._value.label) - - @property - def entity_id(self): - """ Returns the entity_id of the device if any. - The entity_id contains node_id and value instance id - to not collide with other entity_ids""" - - entity_id = "sensor.{}_{}".format(slugify(self.name), - self._node.node_id) - - # Add the instance id if there is more than one instance for the value - if self._value.instance > 1: - return "{}_{}".format(entity_id, self._value.instance) - - return entity_id - @property def state(self): """ Returns the state of the sensor. """ return self._value.data - @property - def state_attributes(self): - """ Returns the state attributes. """ - attrs = { - zwave.ATTR_NODE_ID: self._node.node_id, - } - - battery_level = self._node.get_battery_level() - - if battery_level is not None: - attrs[ATTR_BATTERY_LEVEL] = battery_level - - location = self._node.location - - if location: - attrs[ATTR_LOCATION] = location - - return attrs - @property def unit_of_measurement(self): return self._value.units diff --git a/homeassistant/components/switch/zwave.py b/homeassistant/components/switch/zwave.py index e3229af5314..d3a268b165f 100644 --- a/homeassistant/components/switch/zwave.py +++ b/homeassistant/components/switch/zwave.py @@ -9,7 +9,9 @@ Zwave platform that handles simple binary switches. import homeassistant.components.zwave as zwave from homeassistant.components.switch import SwitchDevice -from homeassistant.util import slugify +from homeassistant.components.zwave import ZWaveDeviceEntity + +DOMAIN = "switch" # pylint: disable=unused-argument @@ -32,14 +34,13 @@ def setup_platform(hass, config, add_devices, discovery_info=None): add_devices([ZwaveSwitch(value)]) -class ZwaveSwitch(SwitchDevice): +class ZwaveSwitch(ZWaveDeviceEntity, SwitchDevice): """ Provides a zwave switch. """ def __init__(self, value): from openzwave.network import ZWaveNetwork from pydispatch import dispatcher - self._value = value - self._node = value.node + ZWaveDeviceEntity.__init__(self, value, DOMAIN) self._state = value.data dispatcher.connect( @@ -51,39 +52,6 @@ class ZwaveSwitch(SwitchDevice): self._state = value.data self.update_ha_state() - @property - def should_poll(self): - """ No polling needed for a demo switch. """ - return False - - @property - def unique_id(self): - """ Returns a unique id. """ - return "ZWAVE-{}-{}".format(self._node.node_id, self._value.object_id) - - @property - def name(self): - """ Returns the name of the device. """ - name = self._node.name or "{} {}".format( - self._node.manufacturer_name, self._node.product_name) - - return "{} {}".format(name, self._value.label) - - @property - def entity_id(self): - """ Returns the entity_id of the device if any. - The entity_id contains node_id and value instance id - to not collide with other entity_ids""" - - entity_id = "switch.{}_{}".format(slugify(self.name), - self._node.node_id) - - # Add the instance id if there is more than one instance for the value - if self._value.instance > 1: - return "{}_{}".format(entity_id, self._value.instance) - - return entity_id - @property def is_on(self): """ True if device is on. """ @@ -91,8 +59,8 @@ class ZwaveSwitch(SwitchDevice): def turn_on(self, **kwargs): """ Turn the device on. """ - self._node.set_switch(self._value.value_id, True) + self._value.node.set_switch(self._value.value_id, True) def turn_off(self, **kwargs): """ Turn the device off. """ - self._node.set_switch(self._value.value_id, False) + self._value.node.set_switch(self._value.value_id, False) diff --git a/homeassistant/components/zwave.py b/homeassistant/components/zwave.py index 6b4de82a70a..a46918353ec 100644 --- a/homeassistant/components/zwave.py +++ b/homeassistant/components/zwave.py @@ -10,11 +10,13 @@ import sys import os.path from pprint import pprint - +from homeassistant.util import slugify from homeassistant import bootstrap from homeassistant.const import ( EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP, - EVENT_PLATFORM_DISCOVERED, ATTR_SERVICE, ATTR_DISCOVERED) + EVENT_PLATFORM_DISCOVERED, ATTR_SERVICE, ATTR_DISCOVERED, + ATTR_BATTERY_LEVEL, ATTR_LOCATION) + DOMAIN = "zwave" REQUIREMENTS = ['pydispatcher==2.0.5'] @@ -211,3 +213,62 @@ def setup(hass, config): hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_zwave) return True + + +class ZWaveDeviceEntity: + """ Represents a ZWave node entity within Home Assistant. """ + def __init__(self, value, domain): + self._value = value + self.entity_id = "{}.{}".format(domain, self._object_id()) + + @property + def should_poll(self): + """ False because we will push our own state to HA when changed. """ + return False + + @property + def unique_id(self): + """ Returns a unique id. """ + return "ZWAVE-{}-{}".format(self._value.node.node_id, + self._value.object_id) + + @property + def name(self): + """ Returns the name of the device. """ + name = self._value.node.name or "{} {}".format( + self._value.node.manufacturer_name, self._value.node.product_name) + + return "{} {}".format(name, self._value.label) + + def _object_id(self): + """ Returns the object_id of the device value. + The object_id contains node_id and value instance id + to not collide with other entity_ids""" + + object_id = "{}_{}".format(slugify(self.name), + self._value.node.node_id) + + # Add the instance id if there is more than one instance for the value + if self._value.instance > 1: + return "{}_{}".format(object_id, self._value.instance) + + return object_id + + @property + def state_attributes(self): + """ Returns the state attributes. """ + attrs = { + ATTR_NODE_ID: self._value.node.node_id, + } + + battery_level = self._value.node.get_battery_level() + + if battery_level is not None: + attrs[ATTR_BATTERY_LEVEL] = battery_level + + location = self._value.node.location + + if location: + attrs[ATTR_LOCATION] = location + + return attrs