Config validation for MQTT light platform.
This commit is contained in:
parent
88da42fe62
commit
29a8403741
2 changed files with 87 additions and 40 deletions
|
@ -7,46 +7,85 @@ https://home-assistant.io/components/light.mqtt/
|
|||
import logging
|
||||
from functools import partial
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
import homeassistant.components.mqtt as mqtt
|
||||
from homeassistant.components.light import (
|
||||
ATTR_BRIGHTNESS, ATTR_RGB_COLOR, Light)
|
||||
from homeassistant.const import CONF_NAME
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.template import render_with_possible_json_value
|
||||
from homeassistant.util import convert
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEPENDENCIES = ['mqtt']
|
||||
|
||||
CONF_STATE_TOPIC = 'state_topic'
|
||||
CONF_COMMAND_TOPIC = 'command_topic'
|
||||
CONF_STATE_VALUE_TEMPLATE = 'state_value_template'
|
||||
CONF_BRIGHTNESS_STATE_TOPIC = 'brightness_state_topic'
|
||||
CONF_BRIGHTNESS_COMMAND_TOPIC = 'brightness_command_topic'
|
||||
CONF_BRIGHTNESS_VALUE_TEMPLATE = 'brightness_value_template'
|
||||
CONF_RGB_STATE_TOPIC = 'rgb_state_topic'
|
||||
CONF_RGB_COMMAND_TOPIC = 'rgb_command_topic'
|
||||
CONF_RGB_VALUE_TEMPLATE = 'rgb_value_template'
|
||||
CONF_PAYLOAD_ON = 'payload_on'
|
||||
CONF_PAYLOAD_OFF = 'payload_off'
|
||||
CONF_OPTIMISTIC = 'optimistic'
|
||||
CONF_BRIGHTNESS_SCALE = 'brightness_scale'
|
||||
|
||||
DEFAULT_NAME = 'MQTT Light'
|
||||
DEFAULT_QOS = 0
|
||||
DEFAULT_PAYLOAD_ON = 'ON'
|
||||
DEFAULT_PAYLOAD_OFF = 'OFF'
|
||||
DEFAULT_OPTIMISTIC = False
|
||||
DEFAULT_BRIGHTNESS_SCALE = 255
|
||||
|
||||
DEPENDENCIES = ['mqtt']
|
||||
PLATFORM_SCHEMA = mqtt.MQTT_BASE_PLATFORM_SCHEMA.extend({
|
||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||
vol.Optional(CONF_STATE_TOPIC): mqtt.valid_subscribe_topic,
|
||||
vol.Required(CONF_COMMAND_TOPIC): mqtt.valid_publish_topic,
|
||||
vol.Optional(CONF_STATE_VALUE_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_BRIGHTNESS_STATE_TOPIC): mqtt.valid_subscribe_topic,
|
||||
vol.Optional(CONF_BRIGHTNESS_COMMAND_TOPIC): mqtt.valid_publish_topic,
|
||||
vol.Optional(CONF_BRIGHTNESS_VALUE_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_RGB_STATE_TOPIC): mqtt.valid_subscribe_topic,
|
||||
vol.Optional(CONF_RGB_COMMAND_TOPIC): mqtt.valid_publish_topic,
|
||||
vol.Optional(CONF_RGB_VALUE_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_PAYLOAD_ON, default=DEFAULT_PAYLOAD_ON): cv.string,
|
||||
vol.Optional(CONF_PAYLOAD_OFF, default=DEFAULT_PAYLOAD_OFF): cv.string,
|
||||
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
|
||||
vol.Optional(CONF_BRIGHTNESS_SCALE, default=DEFAULT_BRIGHTNESS_SCALE):
|
||||
vol.All(vol.Coerce(int), vol.Range(min=1)),
|
||||
})
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
|
||||
"""Add MQTT Light."""
|
||||
if config.get('command_topic') is None:
|
||||
_LOGGER.error("Missing required variable: command_topic")
|
||||
return False
|
||||
|
||||
add_devices_callback([MqttLight(
|
||||
hass,
|
||||
convert(config.get('name'), str, DEFAULT_NAME),
|
||||
{key: convert(config.get(key), str) for key in
|
||||
(typ + topic
|
||||
for typ in ('', 'brightness_', 'rgb_')
|
||||
for topic in ('state_topic', 'command_topic'))},
|
||||
{key: convert(config.get(key + '_value_template'), str)
|
||||
for key in ('state', 'brightness', 'rgb')},
|
||||
convert(config.get('qos'), int, DEFAULT_QOS),
|
||||
config[CONF_NAME],
|
||||
{
|
||||
'on': convert(config.get('payload_on'), str, DEFAULT_PAYLOAD_ON),
|
||||
'off': convert(config.get('payload_off'), str, DEFAULT_PAYLOAD_OFF)
|
||||
key: config.get(key) for key in (
|
||||
CONF_STATE_TOPIC,
|
||||
CONF_COMMAND_TOPIC,
|
||||
CONF_BRIGHTNESS_STATE_TOPIC,
|
||||
CONF_BRIGHTNESS_COMMAND_TOPIC,
|
||||
CONF_RGB_STATE_TOPIC,
|
||||
CONF_RGB_COMMAND_TOPIC,
|
||||
)
|
||||
},
|
||||
convert(config.get('optimistic'), bool, DEFAULT_OPTIMISTIC),
|
||||
convert(config.get('brightness_scale'), int, DEFAULT_BRIGHTNESS_SCALE)
|
||||
{
|
||||
'state': config.get(CONF_STATE_VALUE_TEMPLATE),
|
||||
'brightness': config.get(CONF_BRIGHTNESS_VALUE_TEMPLATE),
|
||||
'rgb': config.get(CONF_RGB_VALUE_TEMPLATE)
|
||||
},
|
||||
config[mqtt.CONF_QOS],
|
||||
{
|
||||
'on': config[CONF_PAYLOAD_ON],
|
||||
'off': config[CONF_PAYLOAD_OFF],
|
||||
},
|
||||
config[CONF_OPTIMISTIC],
|
||||
config[CONF_BRIGHTNESS_SCALE],
|
||||
)])
|
||||
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ light:
|
|||
"""
|
||||
import unittest
|
||||
|
||||
from homeassistant.bootstrap import _setup_component
|
||||
from homeassistant.const import STATE_ON, STATE_OFF, ATTR_ASSUMED_STATE
|
||||
import homeassistant.components.light as light
|
||||
from tests.common import (
|
||||
|
@ -78,24 +79,26 @@ class TestLightMQTT(unittest.TestCase):
|
|||
|
||||
def test_fail_setup_if_no_command_topic(self):
|
||||
"""Test if command fails with command topic."""
|
||||
self.assertTrue(light.setup(self.hass, {
|
||||
'light': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert not _setup_component(self.hass, light.DOMAIN, {
|
||||
light.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
}
|
||||
}))
|
||||
})
|
||||
self.assertIsNone(self.hass.states.get('light.test'))
|
||||
|
||||
def test_no_color_or_brightness_if_no_topics(self):
|
||||
"""Test if there is no color and brightness if no topic."""
|
||||
self.assertTrue(light.setup(self.hass, {
|
||||
'light': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, light.DOMAIN, {
|
||||
light.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'test_light_rgb/status',
|
||||
'command_topic': 'test_light_rgb/set',
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_OFF, state.state)
|
||||
|
@ -112,8 +115,9 @@ class TestLightMQTT(unittest.TestCase):
|
|||
|
||||
def test_controlling_state_via_topic(self):
|
||||
"""Test the controlling of the state via topic."""
|
||||
self.assertTrue(light.setup(self.hass, {
|
||||
'light': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, light.DOMAIN, {
|
||||
light.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'test_light_rgb/status',
|
||||
|
@ -126,7 +130,7 @@ class TestLightMQTT(unittest.TestCase):
|
|||
'payload_on': 1,
|
||||
'payload_off': 0
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_OFF, state.state)
|
||||
|
@ -172,8 +176,9 @@ class TestLightMQTT(unittest.TestCase):
|
|||
|
||||
def test_controlling_scale(self):
|
||||
"""Test the controlling scale."""
|
||||
self.assertTrue(light.setup(self.hass, {
|
||||
'light': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, light.DOMAIN, {
|
||||
light.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'test_scale/status',
|
||||
|
@ -185,7 +190,7 @@ class TestLightMQTT(unittest.TestCase):
|
|||
'payload_on': 'on',
|
||||
'payload_off': 'off'
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_OFF, state.state)
|
||||
|
@ -218,8 +223,9 @@ class TestLightMQTT(unittest.TestCase):
|
|||
|
||||
def test_controlling_state_via_topic_with_templates(self):
|
||||
"""Test the setting og the state with a template."""
|
||||
self.assertTrue(light.setup(self.hass, {
|
||||
'light': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, light.DOMAIN, {
|
||||
light.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'test_light_rgb/status',
|
||||
|
@ -230,7 +236,7 @@ class TestLightMQTT(unittest.TestCase):
|
|||
'brightness_value_template': '{{ value_json.hello }}',
|
||||
'rgb_value_template': '{{ value_json.hello | join(",") }}',
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_OFF, state.state)
|
||||
|
@ -252,8 +258,9 @@ class TestLightMQTT(unittest.TestCase):
|
|||
|
||||
def test_sending_mqtt_commands_and_optimistic(self):
|
||||
"""Test the sending of command in optimistic mode."""
|
||||
self.assertTrue(light.setup(self.hass, {
|
||||
'light': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, light.DOMAIN, {
|
||||
light.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'command_topic': 'test_light_rgb/set',
|
||||
|
@ -263,7 +270,7 @@ class TestLightMQTT(unittest.TestCase):
|
|||
'payload_on': 'on',
|
||||
'payload_off': 'off'
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_OFF, state.state)
|
||||
|
@ -310,15 +317,16 @@ class TestLightMQTT(unittest.TestCase):
|
|||
|
||||
def test_show_brightness_if_only_command_topic(self):
|
||||
"""Test the brightness if only a command topic is present."""
|
||||
self.assertTrue(light.setup(self.hass, {
|
||||
'light': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, light.DOMAIN, {
|
||||
light.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'brightness_command_topic': 'test_light_rgb/brightness/set',
|
||||
'command_topic': 'test_light_rgb/set',
|
||||
'state_topic': 'test_light_rgb/status',
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_OFF, state.state)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue