From 3e157428756b4167480c6209df5dde2a6a42513a Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 5 Mar 2015 23:18:22 -0800 Subject: [PATCH] Move device ABCs to separate helper file --- homeassistant/components/light/demo.py | 2 +- homeassistant/components/light/hue.py | 2 +- homeassistant/components/light/tellstick.py | 2 +- .../components/media_player/__init__.py | 2 +- homeassistant/components/sensor/demo.py | 2 +- homeassistant/components/sensor/tellstick.py | 2 +- homeassistant/components/sensor/zwave.py | 2 +- homeassistant/components/switch/demo.py | 2 +- homeassistant/components/switch/tellstick.py | 2 +- homeassistant/components/switch/wemo.py | 2 +- .../components/thermostat/__init__.py | 2 +- homeassistant/helpers/__init__.py | 118 +---------------- homeassistant/helpers/device.py | 120 ++++++++++++++++++ tests/helpers.py | 2 +- 14 files changed, 137 insertions(+), 125 deletions(-) create mode 100644 homeassistant/helpers/device.py diff --git a/homeassistant/components/light/demo.py b/homeassistant/components/light/demo.py index a02677e1876..88bc20e183b 100644 --- a/homeassistant/components/light/demo.py +++ b/homeassistant/components/light/demo.py @@ -1,7 +1,7 @@ """ Provides demo lights. """ import random -from homeassistant.helpers import ToggleDevice +from homeassistant.helpers.device import ToggleDevice from homeassistant.const import STATE_ON, STATE_OFF, DEVICE_DEFAULT_NAME from homeassistant.components.light import ATTR_BRIGHTNESS, ATTR_XY_COLOR diff --git a/homeassistant/components/light/hue.py b/homeassistant/components/light/hue.py index 0249eec8d64..1c5e6048f47 100644 --- a/homeassistant/components/light/hue.py +++ b/homeassistant/components/light/hue.py @@ -6,7 +6,7 @@ from urllib.parse import urlparse from homeassistant.loader import get_component import homeassistant.util as util -from homeassistant.helpers import ToggleDevice +from homeassistant.helpers.device import ToggleDevice from homeassistant.const import CONF_HOST from homeassistant.components.light import ( ATTR_BRIGHTNESS, ATTR_XY_COLOR, ATTR_TRANSITION, diff --git a/homeassistant/components/light/tellstick.py b/homeassistant/components/light/tellstick.py index a204f8e1856..c7648a6902a 100644 --- a/homeassistant/components/light/tellstick.py +++ b/homeassistant/components/light/tellstick.py @@ -3,7 +3,7 @@ import logging # pylint: disable=no-name-in-module, import-error from homeassistant.components.light import ATTR_BRIGHTNESS from homeassistant.const import ATTR_FRIENDLY_NAME -from homeassistant.helpers import ToggleDevice +from homeassistant.helpers.device import ToggleDevice import tellcore.constants as tellcore_constants diff --git a/homeassistant/components/media_player/__init__.py b/homeassistant/components/media_player/__init__.py index 75263f10815..d0d1e7713bb 100644 --- a/homeassistant/components/media_player/__init__.py +++ b/homeassistant/components/media_player/__init__.py @@ -7,7 +7,7 @@ Component to interface with various media players import logging from homeassistant.components import discovery -from homeassistant.helpers import Device +from homeassistant.helpers.device import Device from homeassistant.helpers.device_component import DeviceComponent from homeassistant.const import ( ATTR_ENTITY_ID, SERVICE_TURN_OFF, SERVICE_VOLUME_UP, diff --git a/homeassistant/components/sensor/demo.py b/homeassistant/components/sensor/demo.py index bbfef927488..b4547395240 100644 --- a/homeassistant/components/sensor/demo.py +++ b/homeassistant/components/sensor/demo.py @@ -1,5 +1,5 @@ """ Support for Wink sensors. """ -from homeassistant.helpers import Device +from homeassistant.helpers.device import Device from homeassistant.const import ( TEMP_CELCIUS, ATTR_UNIT_OF_MEASUREMENT, ATTR_FRIENDLY_NAME) diff --git a/homeassistant/components/sensor/tellstick.py b/homeassistant/components/sensor/tellstick.py index 3e72b9d065e..4786ddd7850 100644 --- a/homeassistant/components/sensor/tellstick.py +++ b/homeassistant/components/sensor/tellstick.py @@ -31,7 +31,7 @@ import tellcore.constants as tellcore_constants from homeassistant.const import ( ATTR_FRIENDLY_NAME, ATTR_UNIT_OF_MEASUREMENT, TEMP_CELCIUS) -from homeassistant.helpers import Device +from homeassistant.helpers.device import Device DatatypeDescription = namedtuple("DatatypeDescription", ['name', 'unit']) diff --git a/homeassistant/components/sensor/zwave.py b/homeassistant/components/sensor/zwave.py index ca343466633..2391a4e8b73 100644 --- a/homeassistant/components/sensor/zwave.py +++ b/homeassistant/components/sensor/zwave.py @@ -9,7 +9,7 @@ from openzwave.network import ZWaveNetwork from pydispatch import dispatcher import homeassistant.components.zwave as zwave -from homeassistant.helpers import Device +from homeassistant.helpers.device import Device from homeassistant.const import ( ATTR_BATTERY_LEVEL, ATTR_UNIT_OF_MEASUREMENT, STATE_ON, STATE_OFF, TEMP_CELCIUS, TEMP_FAHRENHEIT, ATTR_LOCATION) diff --git a/homeassistant/components/switch/demo.py b/homeassistant/components/switch/demo.py index e18e12c520a..b952504677e 100644 --- a/homeassistant/components/switch/demo.py +++ b/homeassistant/components/switch/demo.py @@ -1,5 +1,5 @@ """ Demo platform that has two fake switchces. """ -from homeassistant.helpers import ToggleDevice +from homeassistant.helpers.device import ToggleDevice from homeassistant.const import STATE_ON, STATE_OFF, DEVICE_DEFAULT_NAME diff --git a/homeassistant/components/switch/tellstick.py b/homeassistant/components/switch/tellstick.py index e82213a3d0f..17a8128927b 100644 --- a/homeassistant/components/switch/tellstick.py +++ b/homeassistant/components/switch/tellstick.py @@ -3,7 +3,7 @@ import logging from homeassistant.const import ATTR_FRIENDLY_NAME -from homeassistant.helpers import ToggleDevice +from homeassistant.helpers.device import ToggleDevice import tellcore.constants as tellcore_constants diff --git a/homeassistant/components/switch/wemo.py b/homeassistant/components/switch/wemo.py index 0ebc2869c56..b90c008a7d0 100644 --- a/homeassistant/components/switch/wemo.py +++ b/homeassistant/components/switch/wemo.py @@ -1,7 +1,7 @@ """ Support for WeMo switchces. """ import logging -from homeassistant.helpers import ToggleDevice +from homeassistant.helpers.device import ToggleDevice from homeassistant.components.switch import ( ATTR_TODAY_MWH, ATTR_CURRENT_POWER_MWH) diff --git a/homeassistant/components/thermostat/__init__.py b/homeassistant/components/thermostat/__init__.py index 741d46a0ae4..47b5f61700d 100644 --- a/homeassistant/components/thermostat/__init__.py +++ b/homeassistant/components/thermostat/__init__.py @@ -9,7 +9,7 @@ import logging from homeassistant.helpers.device_component import DeviceComponent import homeassistant.util as util -from homeassistant.helpers import Device, extract_entity_ids +from homeassistant.helpers.device import Device from homeassistant.const import ( ATTR_ENTITY_ID, ATTR_TEMPERATURE, ATTR_UNIT_OF_MEASUREMENT, STATE_ON, STATE_OFF) diff --git a/homeassistant/helpers/__init__.py b/homeassistant/helpers/__init__.py index 362e33b54b1..5db4a8b47e7 100644 --- a/homeassistant/helpers/__init__.py +++ b/homeassistant/helpers/__init__.py @@ -3,14 +3,15 @@ Helper methods for components within Home Assistant. """ from datetime import datetime -from homeassistant import NoEntitySpecifiedError - from homeassistant.loader import get_component from homeassistant.const import ( - ATTR_ENTITY_ID, ATTR_FRIENDLY_NAME, STATE_ON, STATE_OFF, CONF_PLATFORM, - CONF_TYPE, DEVICE_DEFAULT_NAME) + ATTR_ENTITY_ID, CONF_PLATFORM, CONF_TYPE, DEVICE_DEFAULT_NAME) from homeassistant.util import ensure_unique_string, slugify +# Deprecated 3/5/2015 - Moved to homeassistant.helpers.device +# pylint: disable=unused-import +from .device import Device, ToggleDevice # noqa + def generate_entity_id(entity_id_format, name, current_ids=None, hass=None): """ Generate a unique entity ID based on given entity IDs or used ids. """ @@ -175,112 +176,3 @@ def platform_devices_from_config(config, domain, hass, device_dict[entity_id] = device return device_dict - - -class Device(object): - """ ABC for Home Assistant devices. """ - # pylint: disable=no-self-use - - hass = None - entity_id = None - - @property - def should_poll(self): - """ - Return True if device has to be polled for state. - False if device pushes its state to HA. - """ - return True - - @property - def unique_id(self): - """ Returns a unique id. """ - return "{}.{}".format(self.__class__, id(self)) - - @property - def name(self): - """ Returns the name of the device. """ - return self.get_name() - - @property - def state(self): - """ Returns the state of the device. """ - return self.get_state() - - @property - def state_attributes(self): - """ Returns the state attributes. """ - return {} - - # DEPRECATION NOTICE: - # Device is moving from getters to properties. - # For now the new properties will call the old functions - # This will be removed in the future. - - def get_name(self): - """ Returns the name of the device if any. """ - return DEVICE_DEFAULT_NAME - - def get_state(self): - """ Returns state of the device. """ - return "Unknown" - - def get_state_attributes(self): - """ Returns optional state attributes. """ - return None - - def update(self): - """ Retrieve latest state from the real device. """ - pass - - def update_ha_state(self, force_refresh=False): - """ - Updates Home Assistant with current state of device. - If force_refresh == True will update device before setting state. - """ - if self.hass is None: - raise RuntimeError("Attribute hass is None for {}".format(self)) - - if self.entity_id is None: - raise NoEntitySpecifiedError( - "No entity specified for device {}".format(self.name)) - - if force_refresh: - self.update() - - attr = self.state_attributes or {} - - if ATTR_FRIENDLY_NAME not in attr and self.name: - attr[ATTR_FRIENDLY_NAME] = self.name - - return self.hass.states.set(self.entity_id, self.state, attr) - - def __eq__(self, other): - return (isinstance(other, Device) and - other.unique_id == self.unique_id) - - def __repr__(self): - return "".format(self.name, self.state) - - -class ToggleDevice(Device): - """ ABC for devices that can be turned on and off. """ - # pylint: disable=no-self-use - - @property - def state(self): - """ Returns the state. """ - return STATE_ON if self.is_on else STATE_OFF - - @property - def is_on(self): - """ True if device is on. """ - return False - - def turn_on(self, **kwargs): - """ Turn the device on. """ - pass - - def turn_off(self, **kwargs): - """ Turn the device off. """ - pass diff --git a/homeassistant/helpers/device.py b/homeassistant/helpers/device.py new file mode 100644 index 00000000000..017d2673f70 --- /dev/null +++ b/homeassistant/helpers/device.py @@ -0,0 +1,120 @@ +""" +homeassistant.helpers.device +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Provides ABC for devices in HA. +""" + +from homeassistant import NoEntitySpecifiedError + +from homeassistant.const import ( + ATTR_FRIENDLY_NAME, STATE_ON, STATE_OFF, DEVICE_DEFAULT_NAME) + + +class Device(object): + """ ABC for Home Assistant devices. """ + # pylint: disable=no-self-use + + hass = None + entity_id = None + + @property + def should_poll(self): + """ + Return True if device has to be polled for state. + False if device pushes its state to HA. + """ + return True + + @property + def unique_id(self): + """ Returns a unique id. """ + return "{}.{}".format(self.__class__, id(self)) + + @property + def name(self): + """ Returns the name of the device. """ + return self.get_name() + + @property + def state(self): + """ Returns the state of the device. """ + return self.get_state() + + @property + def state_attributes(self): + """ Returns the state attributes. """ + return {} + + # DEPRECATION NOTICE: + # Device is moving from getters to properties. + # For now the new properties will call the old functions + # This will be removed in the future. + + def get_name(self): + """ Returns the name of the device if any. """ + return DEVICE_DEFAULT_NAME + + def get_state(self): + """ Returns state of the device. """ + return "Unknown" + + def get_state_attributes(self): + """ Returns optional state attributes. """ + return None + + def update(self): + """ Retrieve latest state from the real device. """ + pass + + def update_ha_state(self, force_refresh=False): + """ + Updates Home Assistant with current state of device. + If force_refresh == True will update device before setting state. + """ + if self.hass is None: + raise RuntimeError("Attribute hass is None for {}".format(self)) + + if self.entity_id is None: + raise NoEntitySpecifiedError( + "No entity specified for device {}".format(self.name)) + + if force_refresh: + self.update() + + attr = self.state_attributes or {} + + if ATTR_FRIENDLY_NAME not in attr and self.name: + attr[ATTR_FRIENDLY_NAME] = self.name + + return self.hass.states.set(self.entity_id, self.state, attr) + + def __eq__(self, other): + return (isinstance(other, Device) and + other.unique_id == self.unique_id) + + def __repr__(self): + return "".format(self.name, self.state) + + +class ToggleDevice(Device): + """ ABC for devices that can be turned on and off. """ + # pylint: disable=no-self-use + + @property + def state(self): + """ Returns the state. """ + return STATE_ON if self.is_on else STATE_OFF + + @property + def is_on(self): + """ True if device is on. """ + return False + + def turn_on(self, **kwargs): + """ Turn the device on. """ + pass + + def turn_off(self, **kwargs): + """ Turn the device off. """ + pass diff --git a/tests/helpers.py b/tests/helpers.py index 154717397d3..f08df8c4e80 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -7,7 +7,7 @@ Helper method for writing tests. import os import homeassistant as ha -from homeassistant.helpers import ToggleDevice +from homeassistant.helpers.device import ToggleDevice from homeassistant.const import STATE_ON, STATE_OFF, DEVICE_DEFAULT_NAME