mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Add mochad light component (#8476)
* Add mochad light component This commit adds a new component to control x10 dimmers/lights with mochad. * Create comm_type and address constants The comm_type and address conf constants are shared between all mochad devices because they are required information used for configuring a device. This commit moves the definition into const.py so they're consistent between all component types.
This commit is contained in:
parent
d8cded637c
commit
57dfe378a1
99
homeassistant/components/light/mochad.py
Normal file
99
homeassistant/components/light/mochad.py
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
"""
|
||||||
|
Contains functionality to use a X10 dimmer over Mochad.
|
||||||
|
|
||||||
|
For more details about this platform, please refer to the documentation at
|
||||||
|
https://home.assistant.io/components/light.mochad/
|
||||||
|
"""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.components.light import (
|
||||||
|
ATTR_BRIGHTNESS, SUPPORT_BRIGHTNESS, Light, PLATFORM_SCHEMA)
|
||||||
|
from homeassistant.components import mochad
|
||||||
|
from homeassistant.const import (CONF_NAME, CONF_PLATFORM, CONF_DEVICES,
|
||||||
|
CONF_ADDRESS)
|
||||||
|
from homeassistant.helpers import config_validation as cv
|
||||||
|
|
||||||
|
DEPENDENCIES = ['mochad']
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||||
|
vol.Required(CONF_PLATFORM): mochad.DOMAIN,
|
||||||
|
CONF_DEVICES: [{
|
||||||
|
vol.Optional(CONF_NAME): cv.string,
|
||||||
|
vol.Required(CONF_ADDRESS): cv.x10_address,
|
||||||
|
vol.Optional(mochad.CONF_COMM_TYPE): cv.string,
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||||
|
"""Set up X10 dimmers over a mochad controller."""
|
||||||
|
devs = config.get(CONF_DEVICES)
|
||||||
|
add_devices([MochadLight(
|
||||||
|
hass, mochad.CONTROLLER.ctrl, dev) for dev in devs])
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class MochadLight(Light):
|
||||||
|
"""Representation of a X10 dimmer over Mochad."""
|
||||||
|
|
||||||
|
def __init__(self, hass, ctrl, dev):
|
||||||
|
"""Initialize a Mochad Light Device."""
|
||||||
|
from pymochad import device
|
||||||
|
|
||||||
|
self._controller = ctrl
|
||||||
|
self._address = dev[CONF_ADDRESS]
|
||||||
|
self._name = dev.get(CONF_NAME,
|
||||||
|
'x10_light_dev_{}'.format(self._address))
|
||||||
|
self._comm_type = dev.get(mochad.CONF_COMM_TYPE, 'pl')
|
||||||
|
self.device = device.Device(ctrl, self._address,
|
||||||
|
comm_type=self._comm_type)
|
||||||
|
self._brightness = 0
|
||||||
|
self._state = self._get_device_status()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def brightness(self):
|
||||||
|
"""Return the birghtness of this light between 0..255."""
|
||||||
|
return self._brightness
|
||||||
|
|
||||||
|
def _get_device_status(self):
|
||||||
|
"""Get the status of the light from mochad."""
|
||||||
|
status = self.device.get_status().rstrip()
|
||||||
|
return status == 'on'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
"""Return the display name of this light."""
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_on(self):
|
||||||
|
"""Return true if the light is on."""
|
||||||
|
return self._state
|
||||||
|
|
||||||
|
@property
|
||||||
|
def supported_features(self):
|
||||||
|
"""Return supported features."""
|
||||||
|
return SUPPORT_BRIGHTNESS
|
||||||
|
|
||||||
|
@property
|
||||||
|
def assumed_state(self):
|
||||||
|
"""X10 devices are normally 1-way so we have to assume the state."""
|
||||||
|
return True
|
||||||
|
|
||||||
|
def turn_on(self, **kwargs):
|
||||||
|
"""Send the command to turn the light on."""
|
||||||
|
self._brightness = kwargs.get(ATTR_BRIGHTNESS, 255)
|
||||||
|
self.device.send_cmd("xdim {}".format(self._brightness))
|
||||||
|
self._controller.read_data()
|
||||||
|
self._state = True
|
||||||
|
|
||||||
|
def turn_off(self, **kwargs):
|
||||||
|
"""Send the command to turn the light on."""
|
||||||
|
self.device.send_cmd('off')
|
||||||
|
self._controller.read_data()
|
||||||
|
self._state = False
|
@ -19,6 +19,8 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
|
|
||||||
CONTROLLER = None
|
CONTROLLER = None
|
||||||
|
|
||||||
|
CONF_COMM_TYPE = 'comm_type'
|
||||||
|
|
||||||
DOMAIN = 'mochad'
|
DOMAIN = 'mochad'
|
||||||
|
|
||||||
CONFIG_SCHEMA = vol.Schema({
|
CONFIG_SCHEMA = vol.Schema({
|
||||||
|
@ -11,21 +11,20 @@ import voluptuous as vol
|
|||||||
|
|
||||||
from homeassistant.components import mochad
|
from homeassistant.components import mochad
|
||||||
from homeassistant.components.switch import SwitchDevice
|
from homeassistant.components.switch import SwitchDevice
|
||||||
from homeassistant.const import (CONF_NAME, CONF_PLATFORM)
|
from homeassistant.const import (CONF_NAME, CONF_DEVICES,
|
||||||
|
CONF_PLATFORM, CONF_ADDRESS)
|
||||||
from homeassistant.helpers import config_validation as cv
|
from homeassistant.helpers import config_validation as cv
|
||||||
|
|
||||||
DEPENDENCIES = ['mochad']
|
DEPENDENCIES = ['mochad']
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
CONF_ADDRESS = 'address'
|
|
||||||
CONF_DEVICES = 'devices'
|
|
||||||
|
|
||||||
PLATFORM_SCHEMA = vol.Schema({
|
PLATFORM_SCHEMA = vol.Schema({
|
||||||
vol.Required(CONF_PLATFORM): mochad.DOMAIN,
|
vol.Required(CONF_PLATFORM): mochad.DOMAIN,
|
||||||
CONF_DEVICES: [{
|
CONF_DEVICES: [{
|
||||||
vol.Optional(CONF_NAME): cv.string,
|
vol.Optional(CONF_NAME): cv.string,
|
||||||
vol.Required(CONF_ADDRESS): cv.x10_address,
|
vol.Required(CONF_ADDRESS): cv.x10_address,
|
||||||
vol.Optional('comm_type'): cv.string,
|
vol.Optional(mochad.CONF_COMM_TYPE): cv.string,
|
||||||
}]
|
}]
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -48,7 +47,7 @@ class MochadSwitch(SwitchDevice):
|
|||||||
self._controller = ctrl
|
self._controller = ctrl
|
||||||
self._address = dev[CONF_ADDRESS]
|
self._address = dev[CONF_ADDRESS]
|
||||||
self._name = dev.get(CONF_NAME, 'x10_switch_dev_%s' % self._address)
|
self._name = dev.get(CONF_NAME, 'x10_switch_dev_%s' % self._address)
|
||||||
self._comm_type = dev.get('comm_type', 'pl')
|
self._comm_type = dev.get(mochad.CONF_COMM_TYPE, 'pl')
|
||||||
self.device = device.Device(ctrl, self._address,
|
self.device = device.Device(ctrl, self._address,
|
||||||
comm_type=self._comm_type)
|
comm_type=self._comm_type)
|
||||||
self._state = self._get_device_status()
|
self._state = self._get_device_status()
|
||||||
|
@ -56,6 +56,7 @@ SUN_EVENT_SUNRISE = 'sunrise'
|
|||||||
# #### CONFIG ####
|
# #### CONFIG ####
|
||||||
CONF_ABOVE = 'above'
|
CONF_ABOVE = 'above'
|
||||||
CONF_ACCESS_TOKEN = 'access_token'
|
CONF_ACCESS_TOKEN = 'access_token'
|
||||||
|
CONF_ADDRESS = 'address'
|
||||||
CONF_AFTER = 'after'
|
CONF_AFTER = 'after'
|
||||||
CONF_ALIAS = 'alias'
|
CONF_ALIAS = 'alias'
|
||||||
CONF_API_KEY = 'api_key'
|
CONF_API_KEY = 'api_key'
|
||||||
|
88
tests/components/light/test_mochad.py
Normal file
88
tests/components/light/test_mochad.py
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
"""The tests for the mochad light platform."""
|
||||||
|
import unittest
|
||||||
|
import unittest.mock as mock
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from homeassistant.components import light
|
||||||
|
from homeassistant.components.light import mochad
|
||||||
|
from homeassistant.setup import setup_component
|
||||||
|
|
||||||
|
from tests.common import get_test_home_assistant
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def pymochad_mock():
|
||||||
|
"""Mock pymochad."""
|
||||||
|
with mock.patch.dict('sys.modules', {
|
||||||
|
'pymochad': mock.MagicMock(),
|
||||||
|
}):
|
||||||
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
class TestMochadSwitchSetup(unittest.TestCase):
|
||||||
|
"""Test the mochad light."""
|
||||||
|
|
||||||
|
PLATFORM = mochad
|
||||||
|
COMPONENT = light
|
||||||
|
THING = 'light'
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
"""Setup things to be run when tests are started."""
|
||||||
|
self.hass = get_test_home_assistant()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
"""Stop everyhing that was started."""
|
||||||
|
self.hass.stop()
|
||||||
|
|
||||||
|
@mock.patch('homeassistant.components.light.mochad.MochadLight')
|
||||||
|
def test_setup_adds_proper_devices(self, mock_light):
|
||||||
|
"""Test if setup adds devices."""
|
||||||
|
good_config = {
|
||||||
|
'mochad': {},
|
||||||
|
'light': {
|
||||||
|
'platform': 'mochad',
|
||||||
|
'devices': [
|
||||||
|
{
|
||||||
|
'name': 'Light1',
|
||||||
|
'address': 'a1',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.assertTrue(setup_component(self.hass, light.DOMAIN, good_config))
|
||||||
|
|
||||||
|
|
||||||
|
class TestMochadLight(unittest.TestCase):
|
||||||
|
"""Test for mochad light platform."""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
"""Setup things to be run when tests are started."""
|
||||||
|
self.hass = get_test_home_assistant()
|
||||||
|
controller_mock = mock.MagicMock()
|
||||||
|
dev_dict = {'address': 'a1', 'name': 'fake_light'}
|
||||||
|
self.light = mochad.MochadLight(self.hass, controller_mock,
|
||||||
|
dev_dict)
|
||||||
|
|
||||||
|
def teardown_method(self, method):
|
||||||
|
"""Stop everything that was started."""
|
||||||
|
self.hass.stop()
|
||||||
|
|
||||||
|
def test_name(self):
|
||||||
|
"""Test the name."""
|
||||||
|
self.assertEqual('fake_light', self.light.name)
|
||||||
|
|
||||||
|
def test_turn_on_with_no_brightness(self):
|
||||||
|
"""Test turn_on."""
|
||||||
|
self.light.turn_on()
|
||||||
|
self.light.device.send_cmd.assert_called_once_with('xdim 255')
|
||||||
|
|
||||||
|
def test_turn_on_with_brightness(self):
|
||||||
|
"""Test turn_on."""
|
||||||
|
self.light.turn_on(brightness=45)
|
||||||
|
self.light.device.send_cmd.assert_called_once_with('xdim 45')
|
||||||
|
|
||||||
|
def test_turn_off(self):
|
||||||
|
"""Test turn_off."""
|
||||||
|
self.light.turn_off()
|
||||||
|
self.light.device.send_cmd.assert_called_once_with('off')
|
Loading…
x
Reference in New Issue
Block a user