Skip to content

Commit

Permalink
Refactor: code moved to new helper and constants file. Also adds supp…
Browse files Browse the repository at this point in the history
…ort for multiple types for switch/light components.
  • Loading branch information
balloob committed Dec 7, 2014
1 parent 513a03f commit 0527760
Show file tree
Hide file tree
Showing 41 changed files with 603 additions and 442 deletions.
6 changes: 4 additions & 2 deletions README.md
Expand Up @@ -55,6 +55,8 @@ After you got the demo mode running it is time to enable some real components an

*Note:* you can append `?api_password=YOUR_PASSWORD` to the url of the web interface to log in automatically.

*Note:* for the light and switch component, you can specify multiple types by using sequential sections: [switch], [switch 2], [switch 3] etc

### Philips Hue
To get Philips Hue working you will have to connect Home Assistant to the Hue bridge.

Expand All @@ -68,7 +70,7 @@ After that add the following lines to your `home-assistant.conf`:

```
[light]
type=hue
platform=hue
```

### Wireless router
Expand All @@ -77,7 +79,7 @@ Your wireless router is used to track which devices are connected. Three differe

```
[device_tracker]
type=netgear
platform=netgear
host=192.168.1.1
username=admin
password=MY_PASSWORD
Expand Down
6 changes: 3 additions & 3 deletions config/home-assistant.conf.example
Expand Up @@ -9,11 +9,11 @@ api_password=mypass
# development=1

[light]
type=hue
platform=hue

[device_tracker]
# The following types are available: netgear, tomato, luci
type=netgear
platform=netgear
host=192.168.1.1
username=admin
password=PASSWORD
Expand All @@ -26,7 +26,7 @@ password=PASSWORD
# hosts=192.168.1.9,192.168.1.12

[switch]
type=wemo
platform=wemo
# Optional: hard code the hosts (comma seperated) to avoid scanning the network
# hosts=192.168.1.9,192.168.1.12

Expand Down
10 changes: 5 additions & 5 deletions ha_test/config/custom_components/light/test.py
Expand Up @@ -6,8 +6,8 @@
Call init before using it in your tests to ensure clean test data.
"""
import homeassistant.components as components
from ha_test.helper import MockToggleDevice
from homeassistant.const import STATE_ON, STATE_OFF
from ha_test.helpers import MockToggleDevice


DEVICES = []
Expand All @@ -18,9 +18,9 @@ def init(empty=False):
global DEVICES

DEVICES = [] if empty else [
MockToggleDevice('Ceiling', components.STATE_ON),
MockToggleDevice('Ceiling', components.STATE_OFF),
MockToggleDevice(None, components.STATE_OFF)
MockToggleDevice('Ceiling', STATE_ON),
MockToggleDevice('Ceiling', STATE_OFF),
MockToggleDevice(None, STATE_OFF)
]


Expand Down
10 changes: 5 additions & 5 deletions ha_test/config/custom_components/switch/test.py
Expand Up @@ -6,8 +6,8 @@
Call init before using it in your tests to ensure clean test data.
"""
import homeassistant.components as components
from ha_test.helper import MockToggleDevice
from homeassistant.const import STATE_ON, STATE_OFF
from ha_test.helpers import MockToggleDevice


DEVICES = []
Expand All @@ -18,9 +18,9 @@ def init(empty=False):
global DEVICES

DEVICES = [] if empty else [
MockToggleDevice('AC', components.STATE_ON),
MockToggleDevice('AC', components.STATE_OFF),
MockToggleDevice(None, components.STATE_OFF)
MockToggleDevice('AC', STATE_ON),
MockToggleDevice('AC', STATE_OFF),
MockToggleDevice(None, STATE_OFF)
]


Expand Down
11 changes: 6 additions & 5 deletions ha_test/helper.py → ha_test/helpers.py
Expand Up @@ -7,7 +7,8 @@
import os

import homeassistant as ha
import homeassistant.components as components
from homeassistant.helpers import ToggleDevice
from homeassistant.const import STATE_ON, STATE_OFF


def get_test_home_assistant():
Expand Down Expand Up @@ -41,7 +42,7 @@ def __init__(self, domain, dependencies=[], setup=None):
self.setup = lambda hass, config: False if setup is None else setup


class MockToggleDevice(components.ToggleDevice):
class MockToggleDevice(ToggleDevice):
""" Provides a mock toggle device. """
def __init__(self, name, state):
self.name = name
Expand All @@ -56,17 +57,17 @@ def get_name(self):
def turn_on(self, **kwargs):
""" Turn the device on. """
self.calls.append(('turn_on', kwargs))
self.state = components.STATE_ON
self.state = STATE_ON

def turn_off(self, **kwargs):
""" Turn the device off. """
self.calls.append(('turn_off', kwargs))
self.state = components.STATE_OFF
self.state = STATE_OFF

def is_on(self):
""" True if device is on. """
self.calls.append(('is_on', {}))
return self.state == components.STATE_ON
return self.state == STATE_ON

def last_call(self, method=None):
if method is None:
Expand Down
28 changes: 16 additions & 12 deletions ha_test/test_component_chromecast.py
Expand Up @@ -9,9 +9,13 @@
import unittest

import homeassistant as ha
import homeassistant.components as components
from homeassistant.const import (
SERVICE_TURN_OFF, SERVICE_VOLUME_UP, SERVICE_VOLUME_DOWN,
SERVICE_MEDIA_PLAY_PAUSE, SERVICE_MEDIA_PLAY, SERVICE_MEDIA_PAUSE,
SERVICE_MEDIA_NEXT_TRACK, SERVICE_MEDIA_PREV_TRACK, ATTR_ENTITY_ID,
CONF_HOSTS)
import homeassistant.components.chromecast as chromecast
from helper import mock_service
from helpers import mock_service


def setUpModule(): # pylint: disable=invalid-name
Expand Down Expand Up @@ -45,14 +49,14 @@ def test_services(self):
Test if the call service methods conver to correct service calls.
"""
services = {
components.SERVICE_TURN_OFF: chromecast.turn_off,
components.SERVICE_VOLUME_UP: chromecast.volume_up,
components.SERVICE_VOLUME_DOWN: chromecast.volume_down,
components.SERVICE_MEDIA_PLAY_PAUSE: chromecast.media_play_pause,
components.SERVICE_MEDIA_PLAY: chromecast.media_play,
components.SERVICE_MEDIA_PAUSE: chromecast.media_pause,
components.SERVICE_MEDIA_NEXT_TRACK: chromecast.media_next_track,
components.SERVICE_MEDIA_PREV_TRACK: chromecast.media_prev_track
SERVICE_TURN_OFF: chromecast.turn_off,
SERVICE_VOLUME_UP: chromecast.volume_up,
SERVICE_VOLUME_DOWN: chromecast.volume_down,
SERVICE_MEDIA_PLAY_PAUSE: chromecast.media_play_pause,
SERVICE_MEDIA_PLAY: chromecast.media_play,
SERVICE_MEDIA_PAUSE: chromecast.media_pause,
SERVICE_MEDIA_NEXT_TRACK: chromecast.media_next_track,
SERVICE_MEDIA_PREV_TRACK: chromecast.media_prev_track
}

for service_name, service_method in services.items():
Expand All @@ -75,7 +79,7 @@ def test_services(self):
self.assertEqual(call.domain, chromecast.DOMAIN)
self.assertEqual(call.service, service_name)
self.assertEqual(call.data,
{components.ATTR_ENTITY_ID: self.test_entity})
{ATTR_ENTITY_ID: self.test_entity})

def test_setup(self):
"""
Expand All @@ -84,4 +88,4 @@ def test_setup(self):
In an ideal world we would create a mock pychromecast API..
"""
self.assertFalse(chromecast.setup(
self.hass, {chromecast.DOMAIN: {ha.CONF_HOSTS: '127.0.0.1'}}))
self.hass, {chromecast.DOMAIN: {CONF_HOSTS: '127.0.0.1'}}))
24 changes: 6 additions & 18 deletions ha_test/test_component_core.py
Expand Up @@ -9,6 +9,8 @@

import homeassistant as ha
import homeassistant.loader as loader
from homeassistant.const import (
STATE_ON, STATE_OFF, SERVICE_TURN_ON, SERVICE_TURN_OFF)
import homeassistant.components as comps


Expand All @@ -21,8 +23,8 @@ def setUp(self): # pylint: disable=invalid-name
loader.prepare(self.hass)
self.assertTrue(comps.setup(self.hass, {}))

self.hass.states.set('light.Bowl', comps.STATE_ON)
self.hass.states.set('light.Ceiling', comps.STATE_OFF)
self.hass.states.set('light.Bowl', STATE_ON)
self.hass.states.set('light.Ceiling', STATE_OFF)

def tearDown(self): # pylint: disable=invalid-name
""" Stop down stuff we started. """
Expand All @@ -38,7 +40,7 @@ def test_turn_on(self):
""" Test turn_on method. """
runs = []
self.hass.services.register(
'light', comps.SERVICE_TURN_ON, lambda x: runs.append(1))
'light', SERVICE_TURN_ON, lambda x: runs.append(1))

comps.turn_on(self.hass, 'light.Ceiling')

Expand All @@ -50,24 +52,10 @@ def test_turn_off(self):
""" Test turn_off method. """
runs = []
self.hass.services.register(
'light', comps.SERVICE_TURN_OFF, lambda x: runs.append(1))
'light', SERVICE_TURN_OFF, lambda x: runs.append(1))

comps.turn_off(self.hass, 'light.Bowl')

self.hass._pool.block_till_done()

self.assertEqual(1, len(runs))

def test_extract_entity_ids(self):
""" Test extract_entity_ids method. """
call = ha.ServiceCall('light', 'turn_on',
{comps.ATTR_ENTITY_ID: 'light.Bowl'})

self.assertEqual(['light.Bowl'],
comps.extract_entity_ids(self.hass, call))

call = ha.ServiceCall('light', 'turn_on',
{comps.ATTR_ENTITY_ID: ['light.Bowl']})

self.assertEqual(['light.Bowl'],
comps.extract_entity_ids(self.hass, call))
2 changes: 1 addition & 1 deletion ha_test/test_component_demo.py
Expand Up @@ -9,7 +9,7 @@

import homeassistant as ha
import homeassistant.components.demo as demo
from homeassistant.components import (
from homeassistant.const import (
SERVICE_TURN_ON, SERVICE_TURN_OFF, STATE_ON, STATE_OFF, ATTR_ENTITY_ID)


Expand Down
12 changes: 6 additions & 6 deletions ha_test/test_component_device_scanner.py
Expand Up @@ -12,11 +12,11 @@

import homeassistant as ha
import homeassistant.loader as loader
from homeassistant.components import (
STATE_HOME, STATE_NOT_HOME, ATTR_ENTITY_PICTURE)
from homeassistant.const import (
STATE_HOME, STATE_NOT_HOME, ATTR_ENTITY_PICTURE, CONF_PLATFORM)
import homeassistant.components.device_tracker as device_tracker

from helper import get_test_home_assistant
from helpers import get_test_home_assistant


def setUpModule(): # pylint: disable=invalid-name
Expand Down Expand Up @@ -64,15 +64,15 @@ def test_setup(self):

# Test with non-existing component
self.assertFalse(device_tracker.setup(
self.hass, {device_tracker.DOMAIN: {ha.CONF_TYPE: 'nonexisting'}}
self.hass, {device_tracker.DOMAIN: {CONF_PLATFORM: 'nonexisting'}}
))

# Test with a bad known device file around
with open(self.known_dev_path, 'w') as fil:
fil.write("bad data\nbad data\n")

self.assertFalse(device_tracker.setup(self.hass, {
device_tracker.DOMAIN: {ha.CONF_TYPE: 'test'}
device_tracker.DOMAIN: {CONF_PLATFORM: 'test'}
}))

def test_device_tracker(self):
Expand All @@ -84,7 +84,7 @@ def test_device_tracker(self):
scanner.come_home('dev2')

self.assertTrue(device_tracker.setup(self.hass, {
device_tracker.DOMAIN: {ha.CONF_TYPE: 'test'}
device_tracker.DOMAIN: {CONF_PLATFORM: 'test'}
}))

# Ensure a new known devices file has been created.
Expand Down
32 changes: 16 additions & 16 deletions ha_test/test_component_group.py
Expand Up @@ -9,7 +9,7 @@
import logging

import homeassistant as ha
import homeassistant.components as comps
from homeassistant.const import STATE_ON, STATE_OFF, STATE_HOME, STATE_NOT_HOME
import homeassistant.components.group as group


Expand All @@ -25,9 +25,9 @@ def setUp(self): # pylint: disable=invalid-name
""" Init needed objects. """
self.hass = ha.HomeAssistant()

self.hass.states.set('light.Bowl', comps.STATE_ON)
self.hass.states.set('light.Ceiling', comps.STATE_OFF)
self.hass.states.set('switch.AC', comps.STATE_OFF)
self.hass.states.set('light.Bowl', STATE_ON)
self.hass.states.set('light.Ceiling', STATE_OFF)
self.hass.states.set('switch.AC', STATE_OFF)
group.setup_group(self.hass, 'init_group',
['light.Bowl', 'light.Ceiling'], False)
group.setup_group(self.hass, 'mixed_group',
Expand All @@ -47,27 +47,27 @@ def test_setup_and_monitor_group(self):
self.assertIn(self.group_name, self.hass.states.entity_ids())

group_state = self.hass.states.get(self.group_name)
self.assertEqual(comps.STATE_ON, group_state.state)
self.assertEqual(STATE_ON, group_state.state)
self.assertTrue(group_state.attributes[group.ATTR_AUTO])

# Turn the Bowl off and see if group turns off
self.hass.states.set('light.Bowl', comps.STATE_OFF)
self.hass.states.set('light.Bowl', STATE_OFF)

self.hass._pool.block_till_done()

group_state = self.hass.states.get(self.group_name)
self.assertEqual(comps.STATE_OFF, group_state.state)
self.assertEqual(STATE_OFF, group_state.state)

# Turn the Ceiling on and see if group turns on
self.hass.states.set('light.Ceiling', comps.STATE_ON)
self.hass.states.set('light.Ceiling', STATE_ON)

self.hass._pool.block_till_done()

group_state = self.hass.states.get(self.group_name)
self.assertEqual(comps.STATE_ON, group_state.state)
self.assertEqual(STATE_ON, group_state.state)

# Try to setup a group with mixed groupable states
self.hass.states.set('device_tracker.Paulus', comps.STATE_HOME)
self.hass.states.set('device_tracker.Paulus', STATE_HOME)
self.assertFalse(group.setup_group(
self.hass, 'person_and_light',
['light.Bowl', 'device_tracker.Paulus']))
Expand All @@ -91,20 +91,20 @@ def test_setup_and_monitor_group(self):

def test__get_group_type(self):
""" Test _get_group_type method. """
self.assertEqual('on_off', group._get_group_type(comps.STATE_ON))
self.assertEqual('on_off', group._get_group_type(comps.STATE_OFF))
self.assertEqual('on_off', group._get_group_type(STATE_ON))
self.assertEqual('on_off', group._get_group_type(STATE_OFF))
self.assertEqual('home_not_home',
group._get_group_type(comps.STATE_HOME))
group._get_group_type(STATE_HOME))
self.assertEqual('home_not_home',
group._get_group_type(comps.STATE_NOT_HOME))
group._get_group_type(STATE_NOT_HOME))

# Unsupported state
self.assertIsNone(group._get_group_type('unsupported_state'))

def test_is_on(self):
""" Test is_on method. """
self.assertTrue(group.is_on(self.hass, self.group_name))
self.hass.states.set('light.Bowl', comps.STATE_OFF)
self.hass.states.set('light.Bowl', STATE_OFF)
self.hass._pool.block_till_done()
self.assertFalse(group.is_on(self.hass, self.group_name))

Expand Down Expand Up @@ -159,5 +159,5 @@ def test_setup(self):
group_state = self.hass.states.get(
group.ENTITY_ID_FORMAT.format('second_group'))

self.assertEqual(comps.STATE_ON, group_state.state)
self.assertEqual(STATE_ON, group_state.state)
self.assertFalse(group_state.attributes[group.ATTR_AUTO])

0 comments on commit 0527760

Please sign in to comment.