From b2b82d955cae3fc909260b6e75c7966c49bb827e Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 28 Feb 2015 07:31:39 -0800 Subject: [PATCH] Break demo component into small demo platforms --- homeassistant/components/demo.py | 120 +++----------------- homeassistant/components/light/demo.py | 74 ++++++++++++ homeassistant/components/sensor/demo.py | 50 ++++++++ homeassistant/components/switch/demo.py | 57 ++++++++++ homeassistant/components/thermostat/demo.py | 66 +++++++++++ 5 files changed, 260 insertions(+), 107 deletions(-) create mode 100644 homeassistant/components/light/demo.py create mode 100644 homeassistant/components/sensor/demo.py create mode 100644 homeassistant/components/switch/demo.py create mode 100644 homeassistant/components/thermostat/demo.py diff --git a/homeassistant/components/demo.py b/homeassistant/components/demo.py index d5846f450e2..db1dec94351 100644 --- a/homeassistant/components/demo.py +++ b/homeassistant/components/demo.py @@ -4,27 +4,21 @@ homeassistant.components.demo Sets up a demo environment that mimics interaction with devices """ -import random import time import homeassistant as ha +import homeassistant.bootstrap as bootstrap import homeassistant.loader as loader -from homeassistant.helpers import extract_entity_ids from homeassistant.const import ( - SERVICE_TURN_ON, SERVICE_TURN_OFF, - STATE_ON, STATE_OFF, TEMP_CELCIUS, - ATTR_ENTITY_PICTURE, ATTR_ENTITY_ID, ATTR_UNIT_OF_MEASUREMENT, + CONF_PLATFORM, ATTR_ENTITY_PICTURE, STATE_ON, CONF_LATITUDE, CONF_LONGITUDE) -from homeassistant.components.light import ( - ATTR_XY_COLOR, ATTR_RGB_COLOR, ATTR_BRIGHTNESS, GROUP_NAME_ALL_LIGHTS) -from homeassistant.components.thermostat import ( - ATTR_CURRENT_TEMPERATURE, ATTR_AWAY_MODE) -from homeassistant.util import split_entity_id, color_RGB_to_xy DOMAIN = "demo" DEPENDENCIES = [] +COMPONENTS_WITH_DEMO_PLATFORM = ['switch', 'light', 'thermostat', 'sensor'] + def setup(hass, config): """ Setup a demo environment. """ @@ -37,57 +31,6 @@ def setup(hass, config): if config[DOMAIN].get('hide_demo_state') != '1': hass.states.set('a.Demo_Mode', 'Enabled') - light_colors = [ - [0.861, 0.3259], - [0.6389, 0.3028], - [0.1684, 0.0416] - ] - - def mock_turn_on(service): - """ Will fake the component has been turned on. """ - if service.data and ATTR_ENTITY_ID in service.data: - entity_ids = extract_entity_ids(hass, service) - else: - entity_ids = hass.states.entity_ids(service.domain) - - for entity_id in entity_ids: - domain, _ = split_entity_id(entity_id) - - if domain == "light": - rgb_color = service.data.get(ATTR_RGB_COLOR) - - if rgb_color: - color = color_RGB_to_xy( - rgb_color[0], rgb_color[1], rgb_color[2]) - - else: - cur_state = hass.states.get(entity_id) - - # Use current color if available - if cur_state and cur_state.attributes.get(ATTR_XY_COLOR): - color = cur_state.attributes.get(ATTR_XY_COLOR) - else: - color = random.choice(light_colors) - - data = { - ATTR_BRIGHTNESS: service.data.get(ATTR_BRIGHTNESS, 200), - ATTR_XY_COLOR: color - } - else: - data = None - - hass.states.set(entity_id, STATE_ON, data) - - def mock_turn_off(service): - """ Will fake the component has been turned off. """ - if service.data and ATTR_ENTITY_ID in service.data: - entity_ids = extract_entity_ids(hass, service) - else: - entity_ids = hass.states.entity_ids(service.domain) - - for entity_id in entity_ids: - hass.states.set(entity_id, STATE_OFF) - # Setup sun if CONF_LATITUDE not in config[ha.DOMAIN]: config[ha.DOMAIN][CONF_LATITUDE] = '32.87336' @@ -97,34 +40,16 @@ def setup(hass, config): loader.get_component('sun').setup(hass, config) - # Setup fake lights - lights = ['light.Bowl', 'light.Ceiling', 'light.TV_Back_light', - 'light.Bed_light'] - - hass.services.register('light', SERVICE_TURN_ON, mock_turn_on) - hass.services.register('light', SERVICE_TURN_OFF, mock_turn_off) - - mock_turn_on(ha.ServiceCall('light', SERVICE_TURN_ON, - {'entity_id': lights[0:2]})) - mock_turn_off(ha.ServiceCall('light', SERVICE_TURN_OFF, - {'entity_id': lights[2:]})) - - group.setup_group(hass, GROUP_NAME_ALL_LIGHTS, lights, False) - - # Setup switch - switches = ['switch.AC', 'switch.Christmas_Lights'] - - hass.services.register('switch', SERVICE_TURN_ON, mock_turn_on) - hass.services.register('switch', SERVICE_TURN_OFF, mock_turn_off) - - mock_turn_on(ha.ServiceCall('switch', SERVICE_TURN_ON, - {'entity_id': switches[0:1]})) - mock_turn_off(ha.ServiceCall('switch', SERVICE_TURN_OFF, - {'entity_id': switches[1:]})) + # Setup demo platforms + for component in COMPONENTS_WITH_DEMO_PLATFORM: + bootstrap.setup_component( + hass, component, {component: {CONF_PLATFORM: 'demo'}}) # Setup room groups - group.setup_group(hass, 'living room', lights[0:3] + switches[0:1]) - group.setup_group(hass, 'bedroom', [lights[3]] + switches[1:]) + lights = hass.states.entity_ids('light') + switches = hass.states.entity_ids('switch') + group.setup_group(hass, 'living room', [lights[0], lights[1], switches[0]]) + group.setup_group(hass, 'bedroom', [lights[2], switches[1]]) # Setup process hass.states.set("process.XBMC", STATE_ON) @@ -152,26 +77,7 @@ def setup(hass, config): ATTR_ENTITY_PICTURE: 'http://graph.facebook.com/KillBillMovie/picture'}) - # Setup tellstick sensors - hass.states.set("tellstick_sensor.Outside_temperature", "15.6", - { - 'friendly_name': 'Outside temperature', - 'unit_of_measurement': '°C' - }) - hass.states.set("tellstick_sensor.Outside_humidity", "54", - { - 'friendly_name': 'Outside humidity', - 'unit_of_measurement': '%' - }) - - # Nest demo - hass.states.set("thermostat.Nest", "23", - { - ATTR_UNIT_OF_MEASUREMENT: TEMP_CELCIUS, - ATTR_CURRENT_TEMPERATURE: '18', - ATTR_AWAY_MODE: STATE_OFF - }) - + # Setup configurator configurator_ids = [] def hue_configuration_callback(data): diff --git a/homeassistant/components/light/demo.py b/homeassistant/components/light/demo.py new file mode 100644 index 00000000000..edd8d680800 --- /dev/null +++ b/homeassistant/components/light/demo.py @@ -0,0 +1,74 @@ +""" Provides demo lights. """ +import random + +from homeassistant.helpers import ToggleDevice +from homeassistant.const import ( + STATE_ON, STATE_OFF, DEVICE_DEFAULT_NAME, ATTR_FRIENDLY_NAME) +from homeassistant.components.light import ATTR_BRIGHTNESS, ATTR_XY_COLOR + + +LIGHT_COLORS = [ + [0.861, 0.3259], + [0.6389, 0.3028], + [0.1684, 0.0416] +] + + +def setup_platform(hass, config, add_devices_callback, discovery_info=None): + """ Find and return demo lights. """ + add_devices_callback([ + DemoLight("Bed Light", STATE_OFF), + DemoLight("Ceiling", STATE_ON), + DemoLight("Kitchen", STATE_ON) + ]) + + +class DemoLight(ToggleDevice): + """ Provides a demo switch. """ + def __init__(self, name, state, xy=None, brightness=180): + self._name = name or DEVICE_DEFAULT_NAME + self._state = state + self._xy = xy or random.choice(LIGHT_COLORS) + self._brightness = brightness + + @property + def name(self): + """ Returns the name of the device if any. """ + return self._name + + @property + def state(self): + """ Returns the name of the device if any. """ + return self._state + + @property + def state_attributes(self): + """ Returns optional state attributes. """ + attr = { + ATTR_FRIENDLY_NAME: self._name, + } + + if self.is_on: + attr[ATTR_BRIGHTNESS] = self._brightness + attr[ATTR_XY_COLOR] = self._xy + + return attr + + @property + def is_on(self): + """ True if device is on. """ + return self._state == STATE_ON + + def turn_on(self, **kwargs): + """ Turn the device on. """ + self._state = STATE_ON + + if ATTR_XY_COLOR in kwargs: + self._xy = kwargs[ATTR_XY_COLOR] + + if ATTR_BRIGHTNESS in kwargs: + self._brightness = kwargs[ATTR_BRIGHTNESS] + + def turn_off(self, **kwargs): + """ Turn the device off. """ + self._state = STATE_OFF diff --git a/homeassistant/components/sensor/demo.py b/homeassistant/components/sensor/demo.py new file mode 100644 index 00000000000..a9acbd22116 --- /dev/null +++ b/homeassistant/components/sensor/demo.py @@ -0,0 +1,50 @@ +""" Support for Wink sensors. """ +from homeassistant.helpers import Device +from homeassistant.const import ( + TEMP_CELCIUS, ATTR_UNIT_OF_MEASUREMENT, ATTR_FRIENDLY_NAME) + + +def get_devices(hass, config): + """ Find and return Wink sensors. """ + + return get_sensors() + + +def devices_discovered(hass, config, info): + """ Called when a device is discovered. """ + return get_sensors() + + +def get_sensors(): + """ Returns the Wink sensors. """ + return [ + DemoSensor('Outside Temperature', 15.6, TEMP_CELCIUS), + DemoSensor('Outside Humidity', 54, '%'), + ] + + +class DemoSensor(Device): + """ A Demo sensor. """ + + def __init__(self, name, state, unit_of_measurement): + self._name = name + self._state = state + self._unit_of_measurement = unit_of_measurement + + @property + def name(self): + """ Returns the name of the device. """ + return self._name + + @property + def state(self): + """ Returns the state of the device. """ + return self._state + + @property + def state_attributes(self): + """ Returns the state attributes. """ + return { + ATTR_FRIENDLY_NAME: self._name, + ATTR_UNIT_OF_MEASUREMENT: self._unit_of_measurement, + } diff --git a/homeassistant/components/switch/demo.py b/homeassistant/components/switch/demo.py new file mode 100644 index 00000000000..efa049e7194 --- /dev/null +++ b/homeassistant/components/switch/demo.py @@ -0,0 +1,57 @@ +""" Demo platform that has two fake switchces. """ +from homeassistant.helpers import ToggleDevice +from homeassistant.const import ( + STATE_ON, STATE_OFF, DEVICE_DEFAULT_NAME, ATTR_FRIENDLY_NAME) + + +def get_devices(hass, config): + """ Find and return demo switches. """ + return get_switches() + + +def devices_discovered(hass, config, info): + """ Called when a device is discovered. """ + return get_switches() + + +def get_switches(): + """ Returns the Wink switches. """ + return [ + DemoSwitch('Ceiling', STATE_ON), + DemoSwitch('AC', STATE_OFF) + ] + + +class DemoSwitch(ToggleDevice): + """ Provides a demo switch. """ + def __init__(self, name, state): + self._name = name or DEVICE_DEFAULT_NAME + self._state = state + + @property + def name(self): + """ Returns the name of the device if any. """ + return self._name + + @property + def state(self): + """ Returns the name of the device if any. """ + return self._state + + @property + def state_attributes(self): + """ Returns optional state attributes. """ + return {ATTR_FRIENDLY_NAME: self._name} + + @property + def is_on(self): + """ True if device is on. """ + return self._state == STATE_ON + + def turn_on(self, **kwargs): + """ Turn the device on. """ + self._state = STATE_ON + + def turn_off(self, **kwargs): + """ Turn the device off. """ + self._state = STATE_OFF diff --git a/homeassistant/components/thermostat/demo.py b/homeassistant/components/thermostat/demo.py new file mode 100644 index 00000000000..570883ef075 --- /dev/null +++ b/homeassistant/components/thermostat/demo.py @@ -0,0 +1,66 @@ +""" +Demo platform that offers a fake thermostat. +""" + +from homeassistant.components.thermostat import ThermostatDevice +from homeassistant.const import TEMP_CELCIUS, TEMP_FAHRENHEIT + + +# pylint: disable=unused-argument +def get_devices(hass, config): + """ Gets thermostats. """ + + return [ + DemoThermostat("Nest", 21, TEMP_CELCIUS, False, 19), + DemoThermostat("Thermostat", 68, TEMP_FAHRENHEIT, True, 77), + ] + + +# pylint: disable=too-many-arguments +class DemoThermostat(ThermostatDevice): + """ Represents a HeatControl within Home Assistant. """ + + def __init__(self, name, target_temperature, unit_of_measurement, + away, current_temperature): + self._name = name + self._target_temperature = target_temperature + self._unit_of_measurement = unit_of_measurement + self._away = away + self._current_temperature = current_temperature + + @property + def name(self): + """ Returns the name. """ + return self._name + + @property + def unit_of_measurement(self): + """ Returns the unit of measurement. """ + return self._unit_of_measurement + + @property + def current_temperature(self): + """ Returns the current temperature. """ + return self._current_temperature + + @property + def target_temperature(self): + """ Returns the temperature we try to reach. """ + return self._target_temperature + + @property + def is_away_mode_on(self): + """ Returns if away mode is on. """ + return self._away + + def set_temperature(self, temperature): + """ Set new target temperature """ + self._target_temperature = temperature + + def turn_away_mode_on(self): + """ Turns away mode on. """ + self._away = True + + def turn_away_mode_off(self): + """ Turns away mode off. """ + self._away = False