Expand MQTT lights (#6481)
* Add effect support to MQTT Light
* Use effect state topic for supported_features
* Dont use rainbow as default color
* Add color_temp support to MQTT JSON Light
* Add effect to MQTT JSON light
* Support lights in MQTT discovery
* Allow discovered devices to set their platform
* Add white value support to MQTT Light
* Add white value support to MQTT JSON Light
* Remove blank line
* Add color_temp support to MQTT Template light
* Add white value support to MQTT Template Light
* Remove unused SUPPORT_MQTT_TEMPLATE and stale unused flash and transition code from MQTT Template
* Add XY Color to MQTT Light Platform
* Fix syntax
* Fix more syntax errors
* Revert "Remove unused SUPPORT_MQTT_TEMPLATE and stale unused flash and transition code from MQTT Template"
This reverts commit c03798cb63
.
* MQTT Template supports flash and transition but doesnt allow templating of the values
* Add XY color support to MQTT JSON
* Proper variable names
* Only allow whitelisted MQTT platforms to be loaded via MQTT Discovery
* Minor tweaks.
pull/6488/head
parent
c937a7bcb0
commit
2b97449d98
|
@ -12,55 +12,81 @@ import voluptuous as vol
|
|||
from homeassistant.core import callback
|
||||
import homeassistant.components.mqtt as mqtt
|
||||
from homeassistant.components.light import (
|
||||
ATTR_BRIGHTNESS, ATTR_RGB_COLOR, ATTR_COLOR_TEMP, SUPPORT_BRIGHTNESS,
|
||||
SUPPORT_RGB_COLOR, SUPPORT_COLOR_TEMP, Light)
|
||||
ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_EFFECT, ATTR_RGB_COLOR,
|
||||
ATTR_WHITE_VALUE, ATTR_XY_COLOR, Light, SUPPORT_BRIGHTNESS,
|
||||
SUPPORT_COLOR_TEMP, SUPPORT_EFFECT, SUPPORT_RGB_COLOR,
|
||||
SUPPORT_WHITE_VALUE, SUPPORT_XY_COLOR)
|
||||
from homeassistant.const import (
|
||||
CONF_NAME, CONF_OPTIMISTIC, CONF_VALUE_TEMPLATE, CONF_PAYLOAD_OFF,
|
||||
CONF_PAYLOAD_ON, CONF_STATE, CONF_BRIGHTNESS, CONF_RGB,
|
||||
CONF_COLOR_TEMP)
|
||||
CONF_BRIGHTNESS, CONF_COLOR_TEMP, CONF_EFFECT, CONF_NAME,
|
||||
CONF_OPTIMISTIC, CONF_PAYLOAD_OFF, CONF_PAYLOAD_ON,
|
||||
CONF_RGB, CONF_STATE, CONF_VALUE_TEMPLATE, CONF_WHITE_VALUE, CONF_XY)
|
||||
from homeassistant.components.mqtt import (
|
||||
CONF_STATE_TOPIC, CONF_COMMAND_TOPIC, CONF_QOS, CONF_RETAIN)
|
||||
CONF_COMMAND_TOPIC, CONF_QOS, CONF_RETAIN, CONF_STATE_TOPIC)
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEPENDENCIES = ['mqtt']
|
||||
|
||||
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_BRIGHTNESS_SCALE = 'brightness_scale'
|
||||
CONF_COLOR_TEMP_STATE_TOPIC = 'color_temp_state_topic'
|
||||
CONF_BRIGHTNESS_STATE_TOPIC = 'brightness_state_topic'
|
||||
CONF_BRIGHTNESS_VALUE_TEMPLATE = 'brightness_value_template'
|
||||
CONF_COLOR_TEMP_COMMAND_TOPIC = 'color_temp_command_topic'
|
||||
CONF_COLOR_TEMP_STATE_TOPIC = 'color_temp_state_topic'
|
||||
CONF_COLOR_TEMP_VALUE_TEMPLATE = 'color_temp_value_template'
|
||||
CONF_EFFECT_COMMAND_TOPIC = 'effect_command_topic'
|
||||
CONF_EFFECT_LIST = 'effect_list'
|
||||
CONF_EFFECT_STATE_TOPIC = 'effect_state_topic'
|
||||
CONF_EFFECT_VALUE_TEMPLATE = 'effect_value_template'
|
||||
CONF_RGB_COMMAND_TOPIC = 'rgb_command_topic'
|
||||
CONF_RGB_STATE_TOPIC = 'rgb_state_topic'
|
||||
CONF_RGB_VALUE_TEMPLATE = 'rgb_value_template'
|
||||
CONF_STATE_VALUE_TEMPLATE = 'state_value_template'
|
||||
CONF_XY_COMMAND_TOPIC = 'xy_command_topic'
|
||||
CONF_XY_STATE_TOPIC = 'xy_state_topic'
|
||||
CONF_XY_VALUE_TEMPLATE = 'xy_value_template'
|
||||
CONF_WHITE_VALUE_COMMAND_TOPIC = 'white_value_command_topic'
|
||||
CONF_WHITE_VALUE_SCALE = 'white_value_scale'
|
||||
CONF_WHITE_VALUE_STATE_TOPIC = 'white_value_state_topic'
|
||||
CONF_WHITE_VALUE_TEMPLATE = 'white_value_template'
|
||||
|
||||
DEFAULT_NAME = 'MQTT Light'
|
||||
DEFAULT_PAYLOAD_ON = 'ON'
|
||||
DEFAULT_PAYLOAD_OFF = 'OFF'
|
||||
DEFAULT_OPTIMISTIC = False
|
||||
DEFAULT_BRIGHTNESS_SCALE = 255
|
||||
DEFAULT_NAME = 'MQTT Light'
|
||||
DEFAULT_OPTIMISTIC = False
|
||||
DEFAULT_PAYLOAD_OFF = 'OFF'
|
||||
DEFAULT_PAYLOAD_ON = 'ON'
|
||||
DEFAULT_WHITE_VALUE_SCALE = 255
|
||||
|
||||
PLATFORM_SCHEMA = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend({
|
||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||
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_COLOR_TEMP_STATE_TOPIC): mqtt.valid_subscribe_topic,
|
||||
vol.Optional(CONF_COLOR_TEMP_COMMAND_TOPIC): mqtt.valid_publish_topic,
|
||||
vol.Optional(CONF_COLOR_TEMP_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)),
|
||||
vol.Optional(CONF_BRIGHTNESS_STATE_TOPIC): mqtt.valid_subscribe_topic,
|
||||
vol.Optional(CONF_BRIGHTNESS_VALUE_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_COLOR_TEMP_COMMAND_TOPIC): mqtt.valid_publish_topic,
|
||||
vol.Optional(CONF_COLOR_TEMP_STATE_TOPIC): mqtt.valid_subscribe_topic,
|
||||
vol.Optional(CONF_COLOR_TEMP_VALUE_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_EFFECT_COMMAND_TOPIC): mqtt.valid_publish_topic,
|
||||
vol.Optional(CONF_EFFECT_LIST): vol.All(cv.ensure_list, [cv.string]),
|
||||
vol.Optional(CONF_EFFECT_STATE_TOPIC): mqtt.valid_subscribe_topic,
|
||||
vol.Optional(CONF_EFFECT_VALUE_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
|
||||
vol.Optional(CONF_PAYLOAD_OFF, default=DEFAULT_PAYLOAD_OFF): cv.string,
|
||||
vol.Optional(CONF_PAYLOAD_ON, default=DEFAULT_PAYLOAD_ON): cv.string,
|
||||
vol.Optional(CONF_RGB_COMMAND_TOPIC): mqtt.valid_publish_topic,
|
||||
vol.Optional(CONF_RGB_STATE_TOPIC): mqtt.valid_subscribe_topic,
|
||||
vol.Optional(CONF_RGB_VALUE_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_STATE_VALUE_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_WHITE_VALUE_COMMAND_TOPIC): mqtt.valid_publish_topic,
|
||||
vol.Optional(CONF_WHITE_VALUE_SCALE, default=DEFAULT_WHITE_VALUE_SCALE):
|
||||
vol.All(vol.Coerce(int), vol.Range(min=1)),
|
||||
vol.Optional(CONF_WHITE_VALUE_STATE_TOPIC): mqtt.valid_subscribe_topic,
|
||||
vol.Optional(CONF_WHITE_VALUE_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_XY_COMMAND_TOPIC): mqtt.valid_publish_topic,
|
||||
vol.Optional(CONF_XY_STATE_TOPIC): mqtt.valid_subscribe_topic,
|
||||
vol.Optional(CONF_XY_VALUE_TEMPLATE): cv.template,
|
||||
})
|
||||
|
||||
|
||||
|
@ -72,23 +98,33 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
|||
|
||||
async_add_devices([MqttLight(
|
||||
config.get(CONF_NAME),
|
||||
config.get(CONF_EFFECT_LIST),
|
||||
{
|
||||
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,
|
||||
CONF_BRIGHTNESS_STATE_TOPIC,
|
||||
CONF_COLOR_TEMP_COMMAND_TOPIC,
|
||||
CONF_COLOR_TEMP_STATE_TOPIC,
|
||||
CONF_COLOR_TEMP_COMMAND_TOPIC
|
||||
CONF_COMMAND_TOPIC,
|
||||
CONF_EFFECT_COMMAND_TOPIC,
|
||||
CONF_EFFECT_STATE_TOPIC,
|
||||
CONF_RGB_COMMAND_TOPIC,
|
||||
CONF_RGB_STATE_TOPIC,
|
||||
CONF_STATE_TOPIC,
|
||||
CONF_WHITE_VALUE_COMMAND_TOPIC,
|
||||
CONF_WHITE_VALUE_STATE_TOPIC,
|
||||
CONF_XY_COMMAND_TOPIC,
|
||||
CONF_XY_STATE_TOPIC,
|
||||
)
|
||||
},
|
||||
{
|
||||
CONF_STATE: config.get(CONF_STATE_VALUE_TEMPLATE),
|
||||
CONF_BRIGHTNESS: config.get(CONF_BRIGHTNESS_VALUE_TEMPLATE),
|
||||
CONF_COLOR_TEMP: config.get(CONF_COLOR_TEMP_VALUE_TEMPLATE),
|
||||
CONF_EFFECT: config.get(CONF_EFFECT_VALUE_TEMPLATE),
|
||||
CONF_RGB: config.get(CONF_RGB_VALUE_TEMPLATE),
|
||||
CONF_COLOR_TEMP: config.get(CONF_COLOR_TEMP_VALUE_TEMPLATE)
|
||||
CONF_STATE: config.get(CONF_STATE_VALUE_TEMPLATE),
|
||||
CONF_WHITE_VALUE: config.get(CONF_WHITE_VALUE_TEMPLATE),
|
||||
CONF_XY: config.get(CONF_XY_VALUE_TEMPLATE),
|
||||
},
|
||||
config.get(CONF_QOS),
|
||||
config.get(CONF_RETAIN),
|
||||
|
@ -98,16 +134,19 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
|||
},
|
||||
config.get(CONF_OPTIMISTIC),
|
||||
config.get(CONF_BRIGHTNESS_SCALE),
|
||||
config.get(CONF_WHITE_VALUE_SCALE),
|
||||
)])
|
||||
|
||||
|
||||
class MqttLight(Light):
|
||||
"""MQTT light."""
|
||||
|
||||
def __init__(self, name, topic, templates, qos, retain, payload,
|
||||
optimistic, brightness_scale):
|
||||
def __init__(self, name, effect_list, topic, templates, qos,
|
||||
retain, payload, optimistic, brightness_scale,
|
||||
white_value_scale):
|
||||
"""Initialize MQTT light."""
|
||||
self._name = name
|
||||
self._effect_list = effect_list
|
||||
self._topic = topic
|
||||
self._qos = qos
|
||||
self._retain = retain
|
||||
|
@ -120,11 +159,21 @@ class MqttLight(Light):
|
|||
optimistic or topic[CONF_BRIGHTNESS_STATE_TOPIC] is None)
|
||||
self._optimistic_color_temp = (
|
||||
optimistic or topic[CONF_COLOR_TEMP_STATE_TOPIC] is None)
|
||||
self._optimistic_effect = (
|
||||
optimistic or topic[CONF_EFFECT_STATE_TOPIC] is None)
|
||||
self._optimistic_white_value = (
|
||||
optimistic or topic[CONF_WHITE_VALUE_STATE_TOPIC] is None)
|
||||
self._optimistic_xy = \
|
||||
optimistic or topic[CONF_XY_STATE_TOPIC] is None
|
||||
self._brightness_scale = brightness_scale
|
||||
self._white_value_scale = white_value_scale
|
||||
self._state = False
|
||||
self._brightness = None
|
||||
self._rgb = None
|
||||
self._color_temp = None
|
||||
self._effect = None
|
||||
self._white_value = None
|
||||
self._xy = None
|
||||
self._supported_features = 0
|
||||
self._supported_features |= (
|
||||
topic[CONF_RGB_COMMAND_TOPIC] is not None and SUPPORT_RGB_COLOR)
|
||||
|
@ -134,6 +183,14 @@ class MqttLight(Light):
|
|||
self._supported_features |= (
|
||||
topic[CONF_COLOR_TEMP_COMMAND_TOPIC] is not None and
|
||||
SUPPORT_COLOR_TEMP)
|
||||
self._supported_features |= (
|
||||
topic[CONF_EFFECT_STATE_TOPIC] is not None and
|
||||
SUPPORT_EFFECT)
|
||||
self._supported_features |= (
|
||||
topic[CONF_WHITE_VALUE_COMMAND_TOPIC] is not None and
|
||||
SUPPORT_WHITE_VALUE)
|
||||
self._supported_features |= (
|
||||
topic[CONF_XY_COMMAND_TOPIC] is not None and SUPPORT_XY_COLOR)
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_added_to_hass(self):
|
||||
|
@ -215,6 +272,57 @@ class MqttLight(Light):
|
|||
else:
|
||||
self._color_temp = None
|
||||
|
||||
@callback
|
||||
def effect_received(topic, payload, qos):
|
||||
"""A new MQTT message for effect has been received."""
|
||||
self._effect = templates[CONF_EFFECT](payload)
|
||||
self.hass.async_add_job(self.async_update_ha_state())
|
||||
|
||||
if self._topic[CONF_EFFECT_STATE_TOPIC] is not None:
|
||||
yield from mqtt.async_subscribe(
|
||||
self.hass, self._topic[CONF_EFFECT_STATE_TOPIC],
|
||||
effect_received, self._qos)
|
||||
self._effect = 'none'
|
||||
if self._topic[CONF_EFFECT_COMMAND_TOPIC] is not None:
|
||||
self._effect = 'none'
|
||||
else:
|
||||
self._effect = None
|
||||
|
||||
@callback
|
||||
def white_value_received(topic, payload, qos):
|
||||
"""A new MQTT message for the white value has been received."""
|
||||
device_value = float(templates[CONF_WHITE_VALUE](payload))
|
||||
percent_white = device_value / self._white_value_scale
|
||||
self._white_value = int(percent_white * 255)
|
||||
self.hass.async_add_job(self.async_update_ha_state())
|
||||
|
||||
if self._topic[CONF_WHITE_VALUE_STATE_TOPIC] is not None:
|
||||
yield from mqtt.async_subscribe(
|
||||
self.hass, self._topic[CONF_WHITE_VALUE_STATE_TOPIC],
|
||||
white_value_received, self._qos)
|
||||
self._white_value = 255
|
||||
elif self._topic[CONF_WHITE_VALUE_COMMAND_TOPIC] is not None:
|
||||
self._white_value = 255
|
||||
else:
|
||||
self._white_value = None
|
||||
|
||||
@callback
|
||||
def xy_received(topic, payload, qos):
|
||||
"""A new MQTT message has been received."""
|
||||
self._xy = [float(val) for val in
|
||||
templates[CONF_XY](payload).split(',')]
|
||||
self.hass.async_add_job(self.async_update_ha_state())
|
||||
|
||||
if self._topic[CONF_XY_STATE_TOPIC] is not None:
|
||||
yield from mqtt.async_subscribe(
|
||||
self.hass, self._topic[CONF_XY_STATE_TOPIC], xy_received,
|
||||
self._qos)
|
||||
self._xy = [1, 1]
|
||||
if self._topic[CONF_XY_COMMAND_TOPIC] is not None:
|
||||
self._xy = [1, 1]
|
||||
else:
|
||||
self._xy = None
|
||||
|
||||
@property
|
||||
def brightness(self):
|
||||
"""Return the brightness of this light between 0..255."""
|
||||
|
@ -230,6 +338,16 @@ class MqttLight(Light):
|
|||
"""Return the color temperature in mired."""
|
||||
return self._color_temp
|
||||
|
||||
@property
|
||||
def white_value(self):
|
||||
"""Return the white property."""
|
||||
return self._white_value
|
||||
|
||||
@property
|
||||
def xy_color(self):
|
||||
"""Return the RGB color value."""
|
||||
return self._xy
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""No polling needed for a MQTT light."""
|
||||
|
@ -250,6 +368,16 @@ class MqttLight(Light):
|
|||
"""Return true if we do optimistic updates."""
|
||||
return self._optimistic
|
||||
|
||||
@property
|
||||
def effect_list(self):
|
||||
"""Return the list of supported effects."""
|
||||
return self._effect_list
|
||||
|
||||
@property
|
||||
def effect(self):
|
||||
"""Return the current effect."""
|
||||
return self._effect
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
"""Flag supported features."""
|
||||
|
@ -297,6 +425,41 @@ class MqttLight(Light):
|
|||
self._color_temp = kwargs[ATTR_COLOR_TEMP]
|
||||
should_update = True
|
||||
|
||||
if ATTR_EFFECT in kwargs and \
|
||||
self._topic[CONF_EFFECT_COMMAND_TOPIC] is not None:
|
||||
effect = kwargs[ATTR_EFFECT]
|
||||
if effect in self._effect_list:
|
||||
mqtt.async_publish(
|
||||
self.hass, self._topic[CONF_EFFECT_COMMAND_TOPIC],
|
||||
effect, self._qos, self._retain)
|
||||
if self._optimistic_effect:
|
||||
self._effect = kwargs[ATTR_EFFECT]
|
||||
should_update = True
|
||||
|
||||
if ATTR_WHITE_VALUE in kwargs and \
|
||||
self._topic[CONF_WHITE_VALUE_COMMAND_TOPIC] is not None:
|
||||
percent_white = float(kwargs[ATTR_WHITE_VALUE]) / 255
|
||||
device_white_value = int(percent_white * self._white_value_scale)
|
||||
mqtt.async_publish(
|
||||
self.hass, self._topic[CONF_WHITE_VALUE_COMMAND_TOPIC],
|
||||
device_white_value, self._qos, self._retain)
|
||||
|
||||
if self._optimistic_white_value:
|
||||
self._white_value = kwargs[ATTR_WHITE_VALUE]
|
||||
should_update = True
|
||||
|
||||
if ATTR_XY_COLOR in kwargs and \
|
||||
self._topic[CONF_XY_COMMAND_TOPIC] is not None:
|
||||
|
||||
mqtt.async_publish(
|
||||
self.hass, self._topic[CONF_XY_COMMAND_TOPIC],
|
||||
'{},{}'.format(*kwargs[ATTR_XY_COLOR]), self._qos,
|
||||
self._retain)
|
||||
|
||||
if self._optimistic_xy:
|
||||
self._xy = kwargs[ATTR_XY_COLOR]
|
||||
should_update = True
|
||||
|
||||
mqtt.async_publish(
|
||||
self.hass, self._topic[CONF_COMMAND_TOPIC], self._payload['on'],
|
||||
self._qos, self._retain)
|
||||
|
|
|
@ -12,11 +12,14 @@ import voluptuous as vol
|
|||
from homeassistant.core import callback
|
||||
import homeassistant.components.mqtt as mqtt
|
||||
from homeassistant.components.light import (
|
||||
ATTR_BRIGHTNESS, ATTR_RGB_COLOR, ATTR_TRANSITION, PLATFORM_SCHEMA,
|
||||
ATTR_FLASH, FLASH_LONG, FLASH_SHORT, SUPPORT_BRIGHTNESS, SUPPORT_FLASH,
|
||||
SUPPORT_RGB_COLOR, SUPPORT_TRANSITION, Light)
|
||||
ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_EFFECT, ATTR_FLASH,
|
||||
ATTR_RGB_COLOR, ATTR_TRANSITION, ATTR_WHITE_VALUE, ATTR_XY_COLOR,
|
||||
FLASH_LONG, FLASH_SHORT, Light, PLATFORM_SCHEMA, SUPPORT_BRIGHTNESS,
|
||||
SUPPORT_COLOR_TEMP, SUPPORT_EFFECT, SUPPORT_FLASH, SUPPORT_RGB_COLOR,
|
||||
SUPPORT_TRANSITION, SUPPORT_WHITE_VALUE, SUPPORT_XY_COLOR)
|
||||
from homeassistant.const import (
|
||||
CONF_NAME, CONF_OPTIMISTIC, CONF_BRIGHTNESS, CONF_RGB)
|
||||
CONF_BRIGHTNESS, CONF_COLOR_TEMP, CONF_EFFECT,
|
||||
CONF_NAME, CONF_OPTIMISTIC, CONF_RGB, CONF_WHITE_VALUE, CONF_XY)
|
||||
from homeassistant.components.mqtt import (
|
||||
CONF_STATE_TOPIC, CONF_COMMAND_TOPIC, CONF_QOS, CONF_RETAIN)
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
@ -27,34 +30,42 @@ DOMAIN = 'mqtt_json'
|
|||
|
||||
DEPENDENCIES = ['mqtt']
|
||||
|
||||
DEFAULT_BRIGHTNESS = False
|
||||
DEFAULT_COLOR_TEMP = False
|
||||
DEFAULT_EFFECT = False
|
||||
DEFAULT_FLASH_TIME_LONG = 10
|
||||
DEFAULT_FLASH_TIME_SHORT = 2
|
||||
DEFAULT_NAME = 'MQTT JSON Light'
|
||||
DEFAULT_OPTIMISTIC = False
|
||||
DEFAULT_BRIGHTNESS = False
|
||||
DEFAULT_RGB = False
|
||||
DEFAULT_FLASH_TIME_SHORT = 2
|
||||
DEFAULT_FLASH_TIME_LONG = 10
|
||||
DEFAULT_WHITE_VALUE = False
|
||||
DEFAULT_XY = False
|
||||
|
||||
CONF_EFFECT_LIST = 'effect_list'
|
||||
|
||||
CONF_FLASH_TIME_SHORT = 'flash_time_short'
|
||||
CONF_FLASH_TIME_LONG = 'flash_time_long'
|
||||
|
||||
SUPPORT_MQTT_JSON = (SUPPORT_BRIGHTNESS | SUPPORT_FLASH | SUPPORT_RGB_COLOR |
|
||||
SUPPORT_TRANSITION)
|
||||
CONF_FLASH_TIME_SHORT = 'flash_time_short'
|
||||
|
||||
# Stealing some of these from the base MQTT configs.
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
vol.Optional(CONF_QOS, default=mqtt.DEFAULT_QOS):
|
||||
vol.All(vol.Coerce(int), vol.In([0, 1, 2])),
|
||||
vol.Required(CONF_COMMAND_TOPIC): mqtt.valid_publish_topic,
|
||||
vol.Optional(CONF_RETAIN, default=mqtt.DEFAULT_RETAIN): cv.boolean,
|
||||
vol.Optional(CONF_STATE_TOPIC): mqtt.valid_subscribe_topic,
|
||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
|
||||
vol.Optional(CONF_BRIGHTNESS, default=DEFAULT_BRIGHTNESS): cv.boolean,
|
||||
vol.Optional(CONF_RGB, default=DEFAULT_RGB): cv.boolean,
|
||||
vol.Optional(CONF_COLOR_TEMP, default=DEFAULT_COLOR_TEMP): cv.boolean,
|
||||
vol.Optional(CONF_EFFECT, default=DEFAULT_EFFECT): cv.boolean,
|
||||
vol.Optional(CONF_EFFECT_LIST): vol.All(cv.ensure_list, [cv.string]),
|
||||
vol.Optional(CONF_FLASH_TIME_SHORT, default=DEFAULT_FLASH_TIME_SHORT):
|
||||
cv.positive_int,
|
||||
vol.Optional(CONF_FLASH_TIME_LONG, default=DEFAULT_FLASH_TIME_LONG):
|
||||
cv.positive_int
|
||||
cv.positive_int,
|
||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
|
||||
vol.Optional(CONF_QOS, default=mqtt.DEFAULT_QOS):
|
||||
vol.All(vol.Coerce(int), vol.In([0, 1, 2])),
|
||||
vol.Optional(CONF_RETAIN, default=mqtt.DEFAULT_RETAIN): cv.boolean,
|
||||
vol.Optional(CONF_RGB, default=DEFAULT_RGB): cv.boolean,
|
||||
vol.Optional(CONF_STATE_TOPIC): mqtt.valid_subscribe_topic,
|
||||
vol.Optional(CONF_WHITE_VALUE, default=DEFAULT_WHITE_VALUE): cv.boolean,
|
||||
vol.Optional(CONF_XY, default=DEFAULT_XY): cv.boolean,
|
||||
vol.Required(CONF_COMMAND_TOPIC): mqtt.valid_publish_topic,
|
||||
})
|
||||
|
||||
|
||||
|
@ -63,6 +74,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
|||
"""Setup a MQTT JSON Light."""
|
||||
async_add_devices([MqttJson(
|
||||
config.get(CONF_NAME),
|
||||
config.get(CONF_EFFECT_LIST),
|
||||
{
|
||||
key: config.get(key) for key in (
|
||||
CONF_STATE_TOPIC,
|
||||
|
@ -73,7 +85,11 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
|||
config.get(CONF_RETAIN),
|
||||
config.get(CONF_OPTIMISTIC),
|
||||
config.get(CONF_BRIGHTNESS),
|
||||
config.get(CONF_COLOR_TEMP),
|
||||
config.get(CONF_EFFECT),
|
||||
config.get(CONF_RGB),
|
||||
config.get(CONF_WHITE_VALUE),
|
||||
config.get(CONF_XY),
|
||||
{
|
||||
key: config.get(key) for key in (
|
||||
CONF_FLASH_TIME_SHORT,
|
||||
|
@ -86,10 +102,12 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
|||
class MqttJson(Light):
|
||||
"""Representation of a MQTT JSON light."""
|
||||
|
||||
def __init__(self, name, topic, qos, retain, optimistic, brightness, rgb,
|
||||
def __init__(self, name, effect_list, topic, qos, retain, optimistic,
|
||||
brightness, color_temp, effect, rgb, white_value, xy,
|
||||
flash_times):
|
||||
"""Initialize MQTT JSON light."""
|
||||
self._name = name
|
||||
self._effect_list = effect_list
|
||||
self._topic = topic
|
||||
self._qos = qos
|
||||
self._retain = retain
|
||||
|
@ -100,13 +118,45 @@ class MqttJson(Light):
|
|||
else:
|
||||
self._brightness = None
|
||||
|
||||
if color_temp:
|
||||
self._color_temp = 150
|
||||
else:
|
||||
self._color_temp = None
|
||||
|
||||
if effect:
|
||||
self._effect = 'none'
|
||||
else:
|
||||
self._effect = None
|
||||
|
||||
if rgb:
|
||||
self._rgb = [0, 0, 0]
|
||||
else:
|
||||
self._rgb = None
|
||||
|
||||
if white_value:
|
||||
self._white_value = 255
|
||||
else:
|
||||
self._white_value = None
|
||||
|
||||
if xy:
|
||||
self._xy = [1, 1]
|
||||
else:
|
||||
self._xy = None
|
||||
|
||||
self._flash_times = flash_times
|
||||
|
||||
self._supported_features = (SUPPORT_TRANSITION | SUPPORT_FLASH)
|
||||
self._supported_features |= (rgb is not None and SUPPORT_RGB_COLOR)
|
||||
self._supported_features |= (brightness is not None and
|
||||
SUPPORT_BRIGHTNESS)
|
||||
self._supported_features |= (color_temp is not None and
|
||||
SUPPORT_COLOR_TEMP)
|
||||
self._supported_features |= (effect is not None and
|
||||
SUPPORT_EFFECT)
|
||||
self._supported_features |= (white_value is not None and
|
||||
SUPPORT_WHITE_VALUE)
|
||||
self._supported_features |= (xy is not None and SUPPORT_XY_COLOR)
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_added_to_hass(self):
|
||||
"""Subscribe mqtt events.
|
||||
|
@ -133,7 +183,7 @@ class MqttJson(Light):
|
|||
except KeyError:
|
||||
pass
|
||||
except ValueError:
|
||||
_LOGGER.warning("Invalid color value received")
|
||||
_LOGGER.warning("Invalid RGB color value received")
|
||||
|
||||
if self._brightness is not None:
|
||||
try:
|
||||
|
@ -143,6 +193,41 @@ class MqttJson(Light):
|
|||
except ValueError:
|
||||
_LOGGER.warning('Invalid brightness value received')
|
||||
|
||||
if self._color_temp is not None:
|
||||
try:
|
||||
self._color_temp = int(values['color_temp'])
|
||||
except KeyError:
|
||||
pass
|
||||
except ValueError:
|
||||
_LOGGER.warning('Invalid color temp value received')
|
||||
|
||||
if self._effect is not None:
|
||||
try:
|
||||
self._effect = values['effect']
|
||||
except KeyError:
|
||||
pass
|
||||
except ValueError:
|
||||
_LOGGER.warning('Invalid effect value received')
|
||||
|
||||
if self._white_value is not None:
|
||||
try:
|
||||
self._white_value = int(values['white_value'])
|
||||
except KeyError:
|
||||
pass
|
||||
except ValueError:
|
||||
_LOGGER.warning('Invalid white value value received')
|
||||
|
||||
if self._xy is not None:
|
||||
try:
|
||||
x_color = float(values['color']['x'])
|
||||
y_color = float(values['color']['y'])
|
||||
|
||||
self._xy = [x_color, y_color]
|
||||
except KeyError:
|
||||
pass
|
||||
except ValueError:
|
||||
_LOGGER.warning("Invalid XY color value received")
|
||||
|
||||
self.hass.async_add_job(self.async_update_ha_state())
|
||||
|
||||
if self._topic[CONF_STATE_TOPIC] is not None:
|
||||
|
@ -155,11 +240,36 @@ class MqttJson(Light):
|
|||
"""Return the brightness of this light between 0..255."""
|
||||
return self._brightness
|
||||
|
||||
@property
|
||||
def color_temp(self):
|
||||
"""Return the color temperature in mired."""
|
||||
return self._color_temp
|
||||
|
||||
@property
|
||||
def effect(self):
|
||||
"""Return the current effect."""
|
||||
return self._effect
|
||||
|
||||
@property
|
||||
def effect_list(self):
|
||||
"""Return the list of supported effects."""
|
||||
return self._effect_list
|
||||
|
||||
@property
|
||||
def rgb_color(self):
|
||||
"""Return the RGB color value."""
|
||||
return self._rgb
|
||||
|
||||
@property
|
||||
def white_value(self):
|
||||
"""Return the white property."""
|
||||
return self._white_value
|
||||
|
||||
@property
|
||||
def xy_color(self):
|
||||
"""Return the XY color value."""
|
||||
return self._xy
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""No polling needed for a MQTT light."""
|
||||
|
@ -183,7 +293,7 @@ class MqttJson(Light):
|
|||
@property
|
||||
def supported_features(self):
|
||||
"""Flag supported features."""
|
||||
return SUPPORT_MQTT_JSON
|
||||
return self._supported_features
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_turn_on(self, **kwargs):
|
||||
|
@ -224,6 +334,37 @@ class MqttJson(Light):
|
|||
self._brightness = kwargs[ATTR_BRIGHTNESS]
|
||||
should_update = True
|
||||
|
||||
if ATTR_COLOR_TEMP in kwargs:
|
||||
message['color_temp'] = int(kwargs[ATTR_COLOR_TEMP])
|
||||
|
||||
if self._optimistic:
|
||||
self._color_temp = kwargs[ATTR_COLOR_TEMP]
|
||||
should_update = True
|
||||
|
||||
if ATTR_EFFECT in kwargs:
|
||||
message['effect'] = kwargs[ATTR_EFFECT]
|
||||
|
||||
if self._optimistic:
|
||||
self._effect = kwargs[ATTR_EFFECT]
|
||||
should_update = True
|
||||
|
||||
if ATTR_WHITE_VALUE in kwargs:
|
||||
message['white_value'] = int(kwargs[ATTR_WHITE_VALUE])
|
||||
|
||||
if self._optimistic:
|
||||
self._white_value = kwargs[ATTR_WHITE_VALUE]
|
||||
should_update = True
|
||||
|
||||
if ATTR_XY_COLOR in kwargs:
|
||||
message['color'] = {
|
||||
'x': kwargs[ATTR_XY_COLOR][0],
|
||||
'y': kwargs[ATTR_XY_COLOR][1]
|
||||
}
|
||||
|
||||
if self._optimistic:
|
||||
self._xy = kwargs[ATTR_XY_COLOR]
|
||||
should_update = True
|
||||
|
||||
mqtt.async_publish(
|
||||
self.hass, self._topic[CONF_COMMAND_TOPIC], json.dumps(message),
|
||||
self._qos, self._retain)
|
||||
|
|
|
@ -11,9 +11,10 @@ import voluptuous as vol
|
|||
from homeassistant.core import callback
|
||||
import homeassistant.components.mqtt as mqtt
|
||||
from homeassistant.components.light import (
|
||||
ATTR_BRIGHTNESS, ATTR_EFFECT, ATTR_FLASH, ATTR_RGB_COLOR, ATTR_TRANSITION,
|
||||
PLATFORM_SCHEMA, SUPPORT_BRIGHTNESS, SUPPORT_EFFECT, SUPPORT_FLASH,
|
||||
SUPPORT_RGB_COLOR, SUPPORT_TRANSITION, Light)
|
||||
ATTR_BRIGHTNESS, ATTR_COLOR_TEMP, ATTR_EFFECT, ATTR_FLASH,
|
||||
ATTR_RGB_COLOR, ATTR_TRANSITION, ATTR_WHITE_VALUE, Light, PLATFORM_SCHEMA,
|
||||
SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP, SUPPORT_EFFECT, SUPPORT_FLASH,
|
||||
SUPPORT_RGB_COLOR, SUPPORT_TRANSITION, SUPPORT_WHITE_VALUE)
|
||||
from homeassistant.const import CONF_NAME, CONF_OPTIMISTIC, STATE_ON, STATE_OFF
|
||||
from homeassistant.components.mqtt import (
|
||||
CONF_STATE_TOPIC, CONF_COMMAND_TOPIC, CONF_QOS, CONF_RETAIN)
|
||||
|
@ -28,36 +29,37 @@ DEPENDENCIES = ['mqtt']
|
|||
DEFAULT_NAME = 'MQTT Template Light'
|
||||
DEFAULT_OPTIMISTIC = False
|
||||
|
||||
CONF_EFFECT_LIST = "effect_list"
|
||||
CONF_COMMAND_ON_TEMPLATE = 'command_on_template'
|
||||
CONF_COMMAND_OFF_TEMPLATE = 'command_off_template'
|
||||
CONF_STATE_TEMPLATE = 'state_template'
|
||||
CONF_BRIGHTNESS_TEMPLATE = 'brightness_template'
|
||||
CONF_RED_TEMPLATE = 'red_template'
|
||||
CONF_GREEN_TEMPLATE = 'green_template'
|
||||
CONF_BLUE_TEMPLATE = 'blue_template'
|
||||
CONF_BRIGHTNESS_TEMPLATE = 'brightness_template'
|
||||
CONF_COLOR_TEMP_TEMPLATE = 'color_temp_template'
|
||||
CONF_COMMAND_OFF_TEMPLATE = 'command_off_template'
|
||||
CONF_COMMAND_ON_TEMPLATE = 'command_on_template'
|
||||
CONF_EFFECT_LIST = 'effect_list'
|
||||
CONF_EFFECT_TEMPLATE = 'effect_template'
|
||||
|
||||
SUPPORT_MQTT_TEMPLATE = (SUPPORT_BRIGHTNESS | SUPPORT_EFFECT | SUPPORT_FLASH |
|
||||
SUPPORT_RGB_COLOR | SUPPORT_TRANSITION)
|
||||
CONF_GREEN_TEMPLATE = 'green_template'
|
||||
CONF_RED_TEMPLATE = 'red_template'
|
||||
CONF_STATE_TEMPLATE = 'state_template'
|
||||
CONF_WHITE_VALUE_TEMPLATE = 'white_value_template'
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||
vol.Optional(CONF_EFFECT_LIST): vol.All(cv.ensure_list, [cv.string]),
|
||||
vol.Required(CONF_COMMAND_TOPIC): mqtt.valid_publish_topic,
|
||||
vol.Optional(CONF_STATE_TOPIC): mqtt.valid_subscribe_topic,
|
||||
vol.Required(CONF_COMMAND_ON_TEMPLATE): cv.template,
|
||||
vol.Required(CONF_COMMAND_OFF_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_STATE_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_BRIGHTNESS_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_RED_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_GREEN_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_BLUE_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_BRIGHTNESS_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_COLOR_TEMP_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_EFFECT_LIST): vol.All(cv.ensure_list, [cv.string]),
|
||||
vol.Optional(CONF_EFFECT_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_GREEN_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
|
||||
vol.Optional(CONF_RED_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_RETAIN, default=mqtt.DEFAULT_RETAIN): cv.boolean,
|
||||
vol.Optional(CONF_STATE_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_STATE_TOPIC): mqtt.valid_subscribe_topic,
|
||||
vol.Optional(CONF_WHITE_VALUE_TEMPLATE): cv.template,
|
||||
vol.Required(CONF_COMMAND_OFF_TEMPLATE): cv.template,
|
||||
vol.Required(CONF_COMMAND_ON_TEMPLATE): cv.template,
|
||||
vol.Required(CONF_COMMAND_TOPIC): mqtt.valid_publish_topic,
|
||||
vol.Optional(CONF_QOS, default=mqtt.DEFAULT_QOS):
|
||||
vol.All(vol.Coerce(int), vol.In([0, 1, 2])),
|
||||
vol.Optional(CONF_RETAIN, default=mqtt.DEFAULT_RETAIN): cv.boolean
|
||||
})
|
||||
|
||||
|
||||
|
@ -76,14 +78,16 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
|||
},
|
||||
{
|
||||
key: config.get(key) for key in (
|
||||
CONF_COMMAND_ON_TEMPLATE,
|
||||
CONF_COMMAND_OFF_TEMPLATE,
|
||||
CONF_STATE_TEMPLATE,
|
||||
CONF_BRIGHTNESS_TEMPLATE,
|
||||
CONF_RED_TEMPLATE,
|
||||
CONF_GREEN_TEMPLATE,
|
||||
CONF_BLUE_TEMPLATE,
|
||||
CONF_EFFECT_TEMPLATE
|
||||
CONF_BRIGHTNESS_TEMPLATE,
|
||||
CONF_COLOR_TEMP_TEMPLATE,
|
||||
CONF_COMMAND_OFF_TEMPLATE,
|
||||
CONF_COMMAND_ON_TEMPLATE,
|
||||
CONF_EFFECT_TEMPLATE,
|
||||
CONF_GREEN_TEMPLATE,
|
||||
CONF_RED_TEMPLATE,
|
||||
CONF_STATE_TEMPLATE,
|
||||
CONF_WHITE_VALUE_TEMPLATE,
|
||||
)
|
||||
},
|
||||
config.get(CONF_OPTIMISTIC),
|
||||
|
@ -114,6 +118,16 @@ class MqttTemplate(Light):
|
|||
else:
|
||||
self._brightness = None
|
||||
|
||||
if self._templates[CONF_COLOR_TEMP_TEMPLATE] is not None:
|
||||
self._color_temp = 255
|
||||
else:
|
||||
self._color_temp = None
|
||||
|
||||
if self._templates[CONF_WHITE_VALUE_TEMPLATE] is not None:
|
||||
self._white_value = 255
|
||||
else:
|
||||
self._white_value = None
|
||||
|
||||
if (self._templates[CONF_RED_TEMPLATE] is not None and
|
||||
self._templates[CONF_GREEN_TEMPLATE] is not None and
|
||||
self._templates[CONF_BLUE_TEMPLATE] is not None):
|
||||
|
@ -156,6 +170,16 @@ class MqttTemplate(Light):
|
|||
except ValueError:
|
||||
_LOGGER.warning('Invalid brightness value received')
|
||||
|
||||
# read color temperature
|
||||
if self._color_temp is not None:
|
||||
try:
|
||||
self._color_temp = int(
|
||||
self._templates[CONF_COLOR_TEMP_TEMPLATE].
|
||||
async_render_with_possible_json_value(payload)
|
||||
)
|
||||
except ValueError:
|
||||
_LOGGER.warning('Invalid color temperature value received')
|
||||
|
||||
# read color
|
||||
if self._rgb is not None:
|
||||
try:
|
||||
|
@ -171,6 +195,16 @@ class MqttTemplate(Light):
|
|||
except ValueError:
|
||||
_LOGGER.warning('Invalid color value received')
|
||||
|
||||
# read white value
|
||||
if self._white_value is not None:
|
||||
try:
|
||||
self._white_value = int(
|
||||
self._templates[CONF_WHITE_VALUE_TEMPLATE].
|
||||
async_render_with_possible_json_value(payload)
|
||||
)
|
||||
except ValueError:
|
||||
_LOGGER.warning('Invalid white value received')
|
||||
|
||||
# read effect
|
||||
if self._templates[CONF_EFFECT_TEMPLATE] is not None:
|
||||
effect = self._templates[CONF_EFFECT_TEMPLATE].\
|
||||
|
@ -194,11 +228,21 @@ class MqttTemplate(Light):
|
|||
"""Return the brightness of this light between 0..255."""
|
||||
return self._brightness
|
||||
|
||||
@property
|
||||
def color_temp(self):
|
||||
"""Return the color temperature in mired."""
|
||||
return self._color_temp
|
||||
|
||||
@property
|
||||
def rgb_color(self):
|
||||
"""Return the RGB color value [int, int, int]."""
|
||||
return self._rgb
|
||||
|
||||
@property
|
||||
def white_value(self):
|
||||
"""Return the white property."""
|
||||
return self._white_value
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""Return True if entity has to be polled for state.
|
||||
|
@ -250,6 +294,13 @@ class MqttTemplate(Light):
|
|||
if self._optimistic:
|
||||
self._brightness = kwargs[ATTR_BRIGHTNESS]
|
||||
|
||||
# color_temp
|
||||
if ATTR_COLOR_TEMP in kwargs:
|
||||
values['color_temp'] = int(kwargs[ATTR_COLOR_TEMP])
|
||||
|
||||
if self._optimistic:
|
||||
self._color_temp = kwargs[ATTR_COLOR_TEMP]
|
||||
|
||||
# color
|
||||
if ATTR_RGB_COLOR in kwargs:
|
||||
values['red'] = kwargs[ATTR_RGB_COLOR][0]
|
||||
|
@ -259,6 +310,13 @@ class MqttTemplate(Light):
|
|||
if self._optimistic:
|
||||
self._rgb = kwargs[ATTR_RGB_COLOR]
|
||||
|
||||
# white value
|
||||
if ATTR_WHITE_VALUE in kwargs:
|
||||
values['white_value'] = int(kwargs[ATTR_WHITE_VALUE])
|
||||
|
||||
if self._optimistic:
|
||||
self._white_value = kwargs[ATTR_WHITE_VALUE]
|
||||
|
||||
# effect
|
||||
if ATTR_EFFECT in kwargs:
|
||||
values['effect'] = kwargs.get(ATTR_EFFECT)
|
||||
|
@ -307,12 +365,16 @@ class MqttTemplate(Light):
|
|||
@property
|
||||
def supported_features(self):
|
||||
"""Flag supported features."""
|
||||
features = 0
|
||||
features = (SUPPORT_FLASH | SUPPORT_TRANSITION)
|
||||
if self._brightness is not None:
|
||||
features = features | SUPPORT_BRIGHTNESS
|
||||
if self._rgb is not None:
|
||||
features = features | SUPPORT_RGB_COLOR
|
||||
if self._effect_list is not None:
|
||||
features = features | SUPPORT_EFFECT
|
||||
if self._color_temp is not None:
|
||||
features = features | SUPPORT_COLOR_TEMP
|
||||
if self._white_value is not None:
|
||||
features = features | SUPPORT_WHITE_VALUE
|
||||
|
||||
return features
|
||||
|
|
|
@ -20,7 +20,13 @@ _LOGGER = logging.getLogger(__name__)
|
|||
TOPIC_MATCHER = re.compile(
|
||||
r'(?P<prefix_topic>\w+)/(?P<component>\w+)/(?P<object_id>\w+)/config')
|
||||
|
||||
SUPPORTED_COMPONENTS = ['binary_sensor', 'sensor']
|
||||
SUPPORTED_COMPONENTS = ['binary_sensor', 'light', 'sensor']
|
||||
|
||||
ALLOWED_PLATFORMS = {
|
||||
'binary_sensor': ['mqtt'],
|
||||
'light': ['mqtt', 'mqtt_json', 'mqtt_template'],
|
||||
'sensor': ['mqtt']
|
||||
}
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
|
@ -48,7 +54,13 @@ def async_start(hass, discovery_topic, hass_config):
|
|||
return
|
||||
|
||||
payload = dict(payload)
|
||||
payload[CONF_PLATFORM] = 'mqtt'
|
||||
platform = payload.get(CONF_PLATFORM, 'mqtt')
|
||||
if platform not in ALLOWED_PLATFORMS.get(component, []):
|
||||
_LOGGER.warning("Platform %s (component %s) is not allowed",
|
||||
platform, component)
|
||||
return
|
||||
|
||||
payload[CONF_PLATFORM] = platform
|
||||
if CONF_STATE_TOPIC not in payload:
|
||||
payload[CONF_STATE_TOPIC] = '{}/{}/{}/state'.format(
|
||||
discovery_topic, component, object_id)
|
||||
|
|
|
@ -87,6 +87,7 @@ CONF_DISCOVERY = 'discovery'
|
|||
CONF_DISPLAY_OPTIONS = 'display_options'
|
||||
CONF_DOMAIN = 'domain'
|
||||
CONF_DOMAINS = 'domains'
|
||||
CONF_EFFECT = 'effect'
|
||||
CONF_ELEVATION = 'elevation'
|
||||
CONF_EMAIL = 'email'
|
||||
CONF_ENTITIES = 'entities'
|
||||
|
@ -153,6 +154,8 @@ CONF_VALUE_TEMPLATE = 'value_template'
|
|||
CONF_VERIFY_SSL = 'verify_ssl'
|
||||
CONF_WEEKDAY = 'weekday'
|
||||
CONF_WHITELIST = 'whitelist'
|
||||
CONF_WHITE_VALUE = 'white_value'
|
||||
CONF_XY = 'xy'
|
||||
CONF_ZONE = 'zone'
|
||||
|
||||
# #### EVENTS ####
|
||||
|
|
|
@ -15,6 +15,21 @@ light:
|
|||
payload_on: "on"
|
||||
payload_off: "off"
|
||||
|
||||
Configuration for XY Version with brightness:
|
||||
|
||||
light:
|
||||
platform: mqtt
|
||||
name: "Office Light XY"
|
||||
state_topic: "office/xy1/light/status"
|
||||
command_topic: "office/xy1/light/switch"
|
||||
brightness_state_topic: "office/xy1/brightness/status"
|
||||
brightness_command_topic: "office/xy1/brightness/set"
|
||||
xy_state_topic: "office/xy1/xy/status"
|
||||
xy_command_topic: "office/xy1/xy/set"
|
||||
qos: 0
|
||||
payload_on: "on"
|
||||
payload_off: "off"
|
||||
|
||||
config without RGB:
|
||||
|
||||
light:
|
||||
|
@ -72,6 +87,42 @@ light:
|
|||
payload_on: "on"
|
||||
payload_off: "off"
|
||||
|
||||
config with brightness and effect
|
||||
|
||||
light:
|
||||
platform: mqtt
|
||||
name: "Office Light Color Temp"
|
||||
state_topic: "office/rgb1/light/status"
|
||||
command_topic: "office/rgb1/light/switch"
|
||||
brightness_state_topic: "office/rgb1/brightness/status"
|
||||
brightness_command_topic: "office/rgb1/brightness/set"
|
||||
brightness_scale: 99
|
||||
effect_state_topic: "office/rgb1/effect/status"
|
||||
effect_command_topic: "office/rgb1/effect/set"
|
||||
effect_list:
|
||||
- rainbow
|
||||
- colorloop
|
||||
qos: 0
|
||||
payload_on: "on"
|
||||
payload_off: "off"
|
||||
|
||||
config for RGB Version with white value and scale:
|
||||
|
||||
light:
|
||||
platform: mqtt
|
||||
name: "Office Light RGB"
|
||||
state_topic: "office/rgb1/light/status"
|
||||
command_topic: "office/rgb1/light/switch"
|
||||
white_value_state_topic: "office/rgb1/white_value/status"
|
||||
white_value_command_topic: "office/rgb1/white_value/set"
|
||||
white_value_scale: 99
|
||||
rgb_state_topic: "office/rgb1/rgb/status"
|
||||
rgb_command_topic: "office/rgb1/rgb/set"
|
||||
rgb_scale: 99
|
||||
qos: 0
|
||||
payload_on: "on"
|
||||
payload_off: "off"
|
||||
|
||||
"""
|
||||
import unittest
|
||||
from unittest import mock
|
||||
|
@ -109,7 +160,7 @@ class TestLightMQTT(unittest.TestCase):
|
|||
})
|
||||
self.assertIsNone(self.hass.states.get('light.test'))
|
||||
|
||||
def test_no_color_or_brightness_or_color_temp_if_no_topics(self): \
|
||||
def test_no_color_brightness_color_temp_white_xy_if_no_topics(self): \
|
||||
# pylint: disable=invalid-name
|
||||
"""Test if there is no color and brightness if no topic."""
|
||||
with assert_setup_component(1):
|
||||
|
@ -127,6 +178,8 @@ class TestLightMQTT(unittest.TestCase):
|
|||
self.assertIsNone(state.attributes.get('rgb_color'))
|
||||
self.assertIsNone(state.attributes.get('brightness'))
|
||||
self.assertIsNone(state.attributes.get('color_temp'))
|
||||
self.assertIsNone(state.attributes.get('white_value'))
|
||||
self.assertIsNone(state.attributes.get('xy_color'))
|
||||
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb/status', 'ON')
|
||||
self.hass.block_till_done()
|
||||
|
@ -136,6 +189,8 @@ class TestLightMQTT(unittest.TestCase):
|
|||
self.assertIsNone(state.attributes.get('rgb_color'))
|
||||
self.assertIsNone(state.attributes.get('brightness'))
|
||||
self.assertIsNone(state.attributes.get('color_temp'))
|
||||
self.assertIsNone(state.attributes.get('white_value'))
|
||||
self.assertIsNone(state.attributes.get('xy_color'))
|
||||
|
||||
def test_controlling_state_via_topic(self): \
|
||||
# pylint: disable=invalid-name
|
||||
|
@ -151,6 +206,12 @@ class TestLightMQTT(unittest.TestCase):
|
|||
'rgb_command_topic': 'test_light_rgb/rgb/set',
|
||||
'color_temp_state_topic': 'test_light_rgb/color_temp/status',
|
||||
'color_temp_command_topic': 'test_light_rgb/color_temp/set',
|
||||
'effect_state_topic': 'test_light_rgb/effect/status',
|
||||
'effect_command_topic': 'test_light_rgb/effect/set',
|
||||
'white_value_state_topic': 'test_light_rgb/white_value/status',
|
||||
'white_value_command_topic': 'test_light_rgb/white_value/set',
|
||||
'xy_state_topic': 'test_light_rgb/xy/status',
|
||||
'xy_command_topic': 'test_light_rgb/xy/set',
|
||||
'qos': '0',
|
||||
'payload_on': 1,
|
||||
'payload_off': 0
|
||||
|
@ -164,6 +225,9 @@ class TestLightMQTT(unittest.TestCase):
|
|||
self.assertIsNone(state.attributes.get('rgb_color'))
|
||||
self.assertIsNone(state.attributes.get('brightness'))
|
||||
self.assertIsNone(state.attributes.get('color_temp'))
|
||||
self.assertIsNone(state.attributes.get('effect'))
|
||||
self.assertIsNone(state.attributes.get('white_value'))
|
||||
self.assertIsNone(state.attributes.get('xy_color'))
|
||||
self.assertIsNone(state.attributes.get(ATTR_ASSUMED_STATE))
|
||||
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb/status', '1')
|
||||
|
@ -174,6 +238,9 @@ class TestLightMQTT(unittest.TestCase):
|
|||
self.assertEqual([255, 255, 255], state.attributes.get('rgb_color'))
|
||||
self.assertEqual(255, state.attributes.get('brightness'))
|
||||
self.assertEqual(150, state.attributes.get('color_temp'))
|
||||
self.assertEqual('none', state.attributes.get('effect'))
|
||||
self.assertEqual(255, state.attributes.get('white_value'))
|
||||
self.assertEqual([1, 1], state.attributes.get('xy_color'))
|
||||
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb/status', '0')
|
||||
self.hass.block_till_done()
|
||||
|
@ -198,6 +265,21 @@ class TestLightMQTT(unittest.TestCase):
|
|||
self.hass.block_till_done()
|
||||
self.assertEqual(300, light_state.attributes['color_temp'])
|
||||
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb/effect/status', 'rainbow')
|
||||
self.hass.block_till_done()
|
||||
light_state = self.hass.states.get('light.test')
|
||||
self.hass.block_till_done()
|
||||
self.assertEqual('rainbow', light_state.attributes['effect'])
|
||||
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb/white_value/status',
|
||||
'100')
|
||||
self.hass.block_till_done()
|
||||
|
||||
light_state = self.hass.states.get('light.test')
|
||||
self.hass.block_till_done()
|
||||
self.assertEqual(100,
|
||||
light_state.attributes['white_value'])
|
||||
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb/status', '1')
|
||||
self.hass.block_till_done()
|
||||
|
||||
|
@ -209,8 +291,16 @@ class TestLightMQTT(unittest.TestCase):
|
|||
self.assertEqual([125, 125, 125],
|
||||
light_state.attributes.get('rgb_color'))
|
||||
|
||||
def test_controlling_scale(self):
|
||||
"""Test the controlling scale."""
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb/xy/status',
|
||||
'0.675,0.322')
|
||||
self.hass.block_till_done()
|
||||
|
||||
light_state = self.hass.states.get('light.test')
|
||||
self.assertEqual([0.675, 0.322],
|
||||
light_state.attributes.get('xy_color'))
|
||||
|
||||
def test_brightness_controlling_scale(self):
|
||||
"""Test the brightness controlling scale."""
|
||||
with assert_setup_component(1):
|
||||
assert setup_component(self.hass, light.DOMAIN, {
|
||||
light.DOMAIN: {
|
||||
|
@ -256,6 +346,53 @@ class TestLightMQTT(unittest.TestCase):
|
|||
self.assertEqual(255,
|
||||
light_state.attributes['brightness'])
|
||||
|
||||
def test_white_value_controlling_scale(self):
|
||||
"""Test the white_value controlling scale."""
|
||||
with assert_setup_component(1):
|
||||
assert setup_component(self.hass, light.DOMAIN, {
|
||||
light.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'test_scale/status',
|
||||
'command_topic': 'test_scale/set',
|
||||
'white_value_state_topic': 'test_scale/white_value/status',
|
||||
'white_value_command_topic': 'test_scale/white_value/set',
|
||||
'white_value_scale': '99',
|
||||
'qos': 0,
|
||||
'payload_on': 'on',
|
||||
'payload_off': 'off'
|
||||
}
|
||||
})
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_OFF, state.state)
|
||||
self.assertIsNone(state.attributes.get('white_value'))
|
||||
self.assertIsNone(state.attributes.get(ATTR_ASSUMED_STATE))
|
||||
|
||||
fire_mqtt_message(self.hass, 'test_scale/status', 'on')
|
||||
self.hass.block_till_done()
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_ON, state.state)
|
||||
self.assertEqual(255, state.attributes.get('white_value'))
|
||||
|
||||
fire_mqtt_message(self.hass, 'test_scale/status', 'off')
|
||||
self.hass.block_till_done()
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_OFF, state.state)
|
||||
|
||||
fire_mqtt_message(self.hass, 'test_scale/status', 'on')
|
||||
self.hass.block_till_done()
|
||||
|
||||
fire_mqtt_message(self.hass, 'test_scale/white_value/status', '99')
|
||||
self.hass.block_till_done()
|
||||
|
||||
light_state = self.hass.states.get('light.test')
|
||||
self.hass.block_till_done()
|
||||
self.assertEqual(255,
|
||||
light_state.attributes['white_value'])
|
||||
|
||||
def test_controlling_state_via_topic_with_templates(self): \
|
||||
# pylint: disable=invalid-name
|
||||
"""Test the setting og the state with a template."""
|
||||
|
@ -266,11 +403,17 @@ class TestLightMQTT(unittest.TestCase):
|
|||
'command_topic': 'test_light_rgb/set',
|
||||
'brightness_state_topic': 'test_light_rgb/brightness/status',
|
||||
'color_temp_state_topic': 'test_light_rgb/color_temp/status',
|
||||
'effect_state_topic': 'test_light_rgb/effect/status',
|
||||
'rgb_state_topic': 'test_light_rgb/rgb/status',
|
||||
'white_value_state_topic': 'test_light_rgb/white_value/status',
|
||||
'xy_state_topic': 'test_light_rgb/xy/status',
|
||||
'state_value_template': '{{ value_json.hello }}',
|
||||
'brightness_value_template': '{{ value_json.hello }}',
|
||||
'color_temp_value_template': '{{ value_json.hello }}',
|
||||
'effect_value_template': '{{ value_json.hello }}',
|
||||
'rgb_value_template': '{{ value_json.hello | join(",") }}',
|
||||
'white_value_template': '{{ value_json.hello }}',
|
||||
'xy_value_template': '{{ value_json.hello | join(",") }}',
|
||||
}}
|
||||
|
||||
with assert_setup_component(1):
|
||||
|
@ -289,6 +432,12 @@ class TestLightMQTT(unittest.TestCase):
|
|||
'{"hello": "50"}')
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb/color_temp/status',
|
||||
'{"hello": "300"}')
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb/effect/status',
|
||||
'{"hello": "rainbow"}')
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb/white_value/status',
|
||||
'{"hello": "75"}')
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb/xy/status',
|
||||
'{"hello": [0.123,0.123]}')
|
||||
self.hass.block_till_done()
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
|
@ -296,6 +445,9 @@ class TestLightMQTT(unittest.TestCase):
|
|||
self.assertEqual(50, state.attributes.get('brightness'))
|
||||
self.assertEqual([1, 2, 3], state.attributes.get('rgb_color'))
|
||||
self.assertEqual(300, state.attributes.get('color_temp'))
|
||||
self.assertEqual('rainbow', state.attributes.get('effect'))
|
||||
self.assertEqual(75, state.attributes.get('white_value'))
|
||||
self.assertEqual([0.123, 0.123], state.attributes.get('xy_color'))
|
||||
|
||||
def test_sending_mqtt_commands_and_optimistic(self): \
|
||||
# pylint: disable=invalid-name
|
||||
|
@ -307,6 +459,9 @@ class TestLightMQTT(unittest.TestCase):
|
|||
'brightness_command_topic': 'test_light_rgb/brightness/set',
|
||||
'rgb_command_topic': 'test_light_rgb/rgb/set',
|
||||
'color_temp_command_topic': 'test_light_rgb/color_temp/set',
|
||||
'effect_command_topic': 'test_light_rgb/effect/set',
|
||||
'white_value_command_topic': 'test_light_rgb/white_value/set',
|
||||
'xy_command_topic': 'test_light_rgb/xy/set',
|
||||
'qos': 2,
|
||||
'payload_on': 'on',
|
||||
'payload_off': 'off'
|
||||
|
@ -337,19 +492,23 @@ class TestLightMQTT(unittest.TestCase):
|
|||
|
||||
self.mock_publish.reset_mock()
|
||||
light.turn_on(self.hass, 'light.test', rgb_color=[75, 75, 75],
|
||||
brightness=50)
|
||||
brightness=50, white_value=80, xy_color=[0.123, 0.123])
|
||||
self.hass.block_till_done()
|
||||
|
||||
self.mock_publish().async_publish.assert_has_calls([
|
||||
mock.call('test_light_rgb/set', 'on', 2, False),
|
||||
mock.call('test_light_rgb/rgb/set', '75,75,75', 2, False),
|
||||
mock.call('test_light_rgb/brightness/set', 50, 2, False),
|
||||
], any_order=True)
|
||||
mock.call('test_light_rgb/set', 'on', 2, False),
|
||||
mock.call('test_light_rgb/rgb/set', '75,75,75', 2, False),
|
||||
mock.call('test_light_rgb/brightness/set', 50, 2, False),
|
||||
mock.call('test_light_rgb/white_value/set', 80, 2, False),
|
||||
mock.call('test_light_rgb/xy/set', '0.123,0.123', 2, False),
|
||||
], any_order=True)
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_ON, state.state)
|
||||
self.assertEqual((75, 75, 75), state.attributes['rgb_color'])
|
||||
self.assertEqual(50, state.attributes['brightness'])
|
||||
self.assertEqual(80, state.attributes['white_value'])
|
||||
self.assertEqual((0.123, 0.123), state.attributes['xy_color'])
|
||||
|
||||
def test_show_brightness_if_only_command_topic(self):
|
||||
"""Test the brightness if only a command topic is present."""
|
||||
|
@ -398,3 +557,75 @@ class TestLightMQTT(unittest.TestCase):
|
|||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_ON, state.state)
|
||||
self.assertEqual(150, state.attributes.get('color_temp'))
|
||||
|
||||
def test_show_effect_only_if_command_topic(self):
|
||||
"""Test the color temp only if a command topic is present."""
|
||||
config = {light.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'effect_command_topic': 'test_light_rgb/effect/set',
|
||||
'command_topic': 'test_light_rgb/set',
|
||||
'state_topic': 'test_light_rgb/status'
|
||||
}}
|
||||
|
||||
with assert_setup_component(1):
|
||||
assert setup_component(self.hass, light.DOMAIN, config)
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_OFF, state.state)
|
||||
self.assertIsNone(state.attributes.get('effect'))
|
||||
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb/status', 'ON')
|
||||
self.hass.block_till_done()
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_ON, state.state)
|
||||
self.assertEqual('none', state.attributes.get('effect'))
|
||||
|
||||
def test_show_white_value_if_only_command_topic(self):
|
||||
"""Test the white_value if only a command topic is present."""
|
||||
config = {light.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'white_value_command_topic': 'test_light_rgb/white_value/set',
|
||||
'command_topic': 'test_light_rgb/set',
|
||||
'state_topic': 'test_light_rgb/status',
|
||||
}}
|
||||
|
||||
with assert_setup_component(1):
|
||||
assert setup_component(self.hass, light.DOMAIN, config)
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_OFF, state.state)
|
||||
self.assertIsNone(state.attributes.get('white_value'))
|
||||
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb/status', 'ON')
|
||||
self.hass.block_till_done()
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_ON, state.state)
|
||||
self.assertEqual(255, state.attributes.get('white_value'))
|
||||
|
||||
def test_show_xy_if_only_command_topic(self):
|
||||
"""Test the xy if only a command topic is present."""
|
||||
config = {light.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'xy_command_topic': 'test_light_rgb/xy/set',
|
||||
'command_topic': 'test_light_rgb/set',
|
||||
'state_topic': 'test_light_rgb/status',
|
||||
}}
|
||||
|
||||
with assert_setup_component(1):
|
||||
assert setup_component(self.hass, light.DOMAIN, config)
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_OFF, state.state)
|
||||
self.assertIsNone(state.attributes.get('xy_color'))
|
||||
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb/status', 'ON')
|
||||
self.hass.block_till_done()
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_ON, state.state)
|
||||
self.assertEqual([1, 1], state.attributes.get('xy_color'))
|
||||
|
|
|
@ -1,6 +1,56 @@
|
|||
"""The tests for the MQTT JSON light platform.
|
||||
|
||||
Configuration for RGB Version with brightness:
|
||||
Configuration with RGB, brightness, color temp, effect, white value and XY:
|
||||
|
||||
light:
|
||||
platform: mqtt_json
|
||||
name: mqtt_json_light_1
|
||||
state_topic: "home/rgb1"
|
||||
command_topic: "home/rgb1/set"
|
||||
brightness: true
|
||||
color_temp: true
|
||||
effect: true
|
||||
rgb: true
|
||||
white_value: true
|
||||
xy: true
|
||||
|
||||
Configuration with RGB, brightness, color temp, effect, white value:
|
||||
|
||||
light:
|
||||
platform: mqtt_json
|
||||
name: mqtt_json_light_1
|
||||
state_topic: "home/rgb1"
|
||||
command_topic: "home/rgb1/set"
|
||||
brightness: true
|
||||
color_temp: true
|
||||
effect: true
|
||||
rgb: true
|
||||
white_value: true
|
||||
|
||||
Configuration with RGB, brightness, color temp and effect:
|
||||
|
||||
light:
|
||||
platform: mqtt_json
|
||||
name: mqtt_json_light_1
|
||||
state_topic: "home/rgb1"
|
||||
command_topic: "home/rgb1/set"
|
||||
brightness: true
|
||||
color_temp: true
|
||||
effect: true
|
||||
rgb: true
|
||||
|
||||
Configuration with RGB, brightness and color temp:
|
||||
|
||||
light:
|
||||
platform: mqtt_json
|
||||
name: mqtt_json_light_1
|
||||
state_topic: "home/rgb1"
|
||||
command_topic: "home/rgb1/set"
|
||||
brightness: true
|
||||
rgb: true
|
||||
color_temp: true
|
||||
|
||||
Configuration with RGB, brightness:
|
||||
|
||||
light:
|
||||
platform: mqtt_json
|
||||
|
@ -62,9 +112,9 @@ class TestLightMQTTJSON(unittest.TestCase):
|
|||
})
|
||||
self.assertIsNone(self.hass.states.get('light.test'))
|
||||
|
||||
def test_no_color_or_brightness_if_no_config(self): \
|
||||
def test_no_color_brightness_color_temp_white_val_if_no_topics(self): \
|
||||
# pylint: disable=invalid-name
|
||||
"""Test if there is no color and brightness if they aren't defined."""
|
||||
"""Test for no RGB, brightness, color temp, effect, white val or XY."""
|
||||
assert setup_component(self.hass, light.DOMAIN, {
|
||||
light.DOMAIN: {
|
||||
'platform': 'mqtt_json',
|
||||
|
@ -78,6 +128,10 @@ class TestLightMQTTJSON(unittest.TestCase):
|
|||
self.assertEqual(STATE_OFF, state.state)
|
||||
self.assertIsNone(state.attributes.get('rgb_color'))
|
||||
self.assertIsNone(state.attributes.get('brightness'))
|
||||
self.assertIsNone(state.attributes.get('color_temp'))
|
||||
self.assertIsNone(state.attributes.get('effect'))
|
||||
self.assertIsNone(state.attributes.get('white_value'))
|
||||
self.assertIsNone(state.attributes.get('xy_color'))
|
||||
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb', '{"state":"ON"}')
|
||||
self.hass.block_till_done()
|
||||
|
@ -86,6 +140,10 @@ class TestLightMQTTJSON(unittest.TestCase):
|
|||
self.assertEqual(STATE_ON, state.state)
|
||||
self.assertIsNone(state.attributes.get('rgb_color'))
|
||||
self.assertIsNone(state.attributes.get('brightness'))
|
||||
self.assertIsNone(state.attributes.get('color_temp'))
|
||||
self.assertIsNone(state.attributes.get('effect'))
|
||||
self.assertIsNone(state.attributes.get('white_value'))
|
||||
self.assertIsNone(state.attributes.get('xy_color'))
|
||||
|
||||
def test_controlling_state_via_topic(self): \
|
||||
# pylint: disable=invalid-name
|
||||
|
@ -97,7 +155,11 @@ class TestLightMQTTJSON(unittest.TestCase):
|
|||
'state_topic': 'test_light_rgb',
|
||||
'command_topic': 'test_light_rgb/set',
|
||||
'brightness': True,
|
||||
'color_temp': True,
|
||||
'effect': True,
|
||||
'rgb': True,
|
||||
'white_value': True,
|
||||
'xy': True,
|
||||
'qos': '0'
|
||||
}
|
||||
})
|
||||
|
@ -106,19 +168,31 @@ class TestLightMQTTJSON(unittest.TestCase):
|
|||
self.assertEqual(STATE_OFF, state.state)
|
||||
self.assertIsNone(state.attributes.get('rgb_color'))
|
||||
self.assertIsNone(state.attributes.get('brightness'))
|
||||
self.assertIsNone(state.attributes.get('color_temp'))
|
||||
self.assertIsNone(state.attributes.get('effect'))
|
||||
self.assertIsNone(state.attributes.get('white_value'))
|
||||
self.assertIsNone(state.attributes.get('xy_color'))
|
||||
self.assertIsNone(state.attributes.get(ATTR_ASSUMED_STATE))
|
||||
|
||||
# Turn on the light, full white
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb',
|
||||
'{"state":"ON",'
|
||||
'"color":{"r":255,"g":255,"b":255},'
|
||||
'"brightness":255}')
|
||||
'"color":{"r":255,"g":255,"b":255,'
|
||||
'"x":0.123,"y":0.123},'
|
||||
'"brightness":255,'
|
||||
'"color_temp":155,'
|
||||
'"effect":"colorloop",'
|
||||
'"white_value":150}')
|
||||
self.hass.block_till_done()
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_ON, state.state)
|
||||
self.assertEqual([255, 255, 255], state.attributes.get('rgb_color'))
|
||||
self.assertEqual(255, state.attributes.get('brightness'))
|
||||
self.assertEqual(155, state.attributes.get('color_temp'))
|
||||
self.assertEqual('colorloop', state.attributes.get('effect'))
|
||||
self.assertEqual(150, state.attributes.get('white_value'))
|
||||
self.assertEqual([0.123, 0.123], state.attributes.get('xy_color'))
|
||||
|
||||
# Turn the light off
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb', '{"state":"OFF"}')
|
||||
|
@ -146,6 +220,39 @@ class TestLightMQTTJSON(unittest.TestCase):
|
|||
self.assertEqual([125, 125, 125],
|
||||
light_state.attributes.get('rgb_color'))
|
||||
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb',
|
||||
'{"state":"ON",'
|
||||
'"color":{"x":0.135,"y":0.135}}')
|
||||
self.hass.block_till_done()
|
||||
|
||||
light_state = self.hass.states.get('light.test')
|
||||
self.assertEqual([0.135, 0.135],
|
||||
light_state.attributes.get('xy_color'))
|
||||
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb',
|
||||
'{"state":"ON",'
|
||||
'"color_temp":155}')
|
||||
self.hass.block_till_done()
|
||||
|
||||
light_state = self.hass.states.get('light.test')
|
||||
self.assertEqual(155, light_state.attributes.get('color_temp'))
|
||||
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb',
|
||||
'{"state":"ON",'
|
||||
'"effect":"colorloop"}')
|
||||
self.hass.block_till_done()
|
||||
|
||||
light_state = self.hass.states.get('light.test')
|
||||
self.assertEqual('colorloop', light_state.attributes.get('effect'))
|
||||
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb',
|
||||
'{"state":"ON",'
|
||||
'"white_value":155}')
|
||||
self.hass.block_till_done()
|
||||
|
||||
light_state = self.hass.states.get('light.test')
|
||||
self.assertEqual(155, light_state.attributes.get('white_value'))
|
||||
|
||||
def test_sending_mqtt_commands_and_optimistic(self): \
|
||||
# pylint: disable=invalid-name
|
||||
"""Test the sending of command in optimistic mode."""
|
||||
|
@ -155,7 +262,10 @@ class TestLightMQTTJSON(unittest.TestCase):
|
|||
'name': 'test',
|
||||
'command_topic': 'test_light_rgb/set',
|
||||
'brightness': True,
|
||||
'color_temp': True,
|
||||
'effect': True,
|
||||
'rgb': True,
|
||||
'white_value': True,
|
||||
'qos': 2
|
||||
}
|
||||
})
|
||||
|
@ -181,7 +291,8 @@ class TestLightMQTTJSON(unittest.TestCase):
|
|||
self.assertEqual(STATE_OFF, state.state)
|
||||
|
||||
light.turn_on(self.hass, 'light.test', rgb_color=[75, 75, 75],
|
||||
brightness=50)
|
||||
brightness=50, color_temp=155, effect='colorloop',
|
||||
white_value=170)
|
||||
self.hass.block_till_done()
|
||||
|
||||
self.assertEqual('test_light_rgb/set',
|
||||
|
@ -191,15 +302,21 @@ class TestLightMQTTJSON(unittest.TestCase):
|
|||
# Get the sent message
|
||||
message_json = json.loads(self.mock_publish.mock_calls[-2][1][1])
|
||||
self.assertEqual(50, message_json["brightness"])
|
||||
self.assertEqual(155, message_json["color_temp"])
|
||||
self.assertEqual('colorloop', message_json["effect"])
|
||||
self.assertEqual(75, message_json["color"]["r"])
|
||||
self.assertEqual(75, message_json["color"]["g"])
|
||||
self.assertEqual(75, message_json["color"]["b"])
|
||||
self.assertEqual(170, message_json["white_value"])
|
||||
self.assertEqual("ON", message_json["state"])
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_ON, state.state)
|
||||
self.assertEqual((75, 75, 75), state.attributes['rgb_color'])
|
||||
self.assertEqual(50, state.attributes['brightness'])
|
||||
self.assertEqual(155, state.attributes['color_temp'])
|
||||
self.assertEqual('colorloop', state.attributes['effect'])
|
||||
self.assertEqual(170, state.attributes['white_value'])
|
||||
|
||||
def test_flash_short_and_long(self): \
|
||||
# pylint: disable=invalid-name
|
||||
|
@ -283,9 +400,9 @@ class TestLightMQTTJSON(unittest.TestCase):
|
|||
self.assertEqual(10, message_json["transition"])
|
||||
self.assertEqual("OFF", message_json["state"])
|
||||
|
||||
def test_invalid_color_and_brightness_values(self): \
|
||||
def test_invalid_color_brightness_and_white_values(self): \
|
||||
# pylint: disable=invalid-name
|
||||
"""Test that invalid color/brightness values are ignored."""
|
||||
"""Test that invalid color/brightness/white values are ignored."""
|
||||
assert setup_component(self.hass, light.DOMAIN, {
|
||||
light.DOMAIN: {
|
||||
'platform': 'mqtt_json',
|
||||
|
@ -294,6 +411,7 @@ class TestLightMQTTJSON(unittest.TestCase):
|
|||
'command_topic': 'test_light_rgb/set',
|
||||
'brightness': True,
|
||||
'rgb': True,
|
||||
'white_value': True,
|
||||
'qos': '0'
|
||||
}
|
||||
})
|
||||
|
@ -302,19 +420,22 @@ class TestLightMQTTJSON(unittest.TestCase):
|
|||
self.assertEqual(STATE_OFF, state.state)
|
||||
self.assertIsNone(state.attributes.get('rgb_color'))
|
||||
self.assertIsNone(state.attributes.get('brightness'))
|
||||
self.assertIsNone(state.attributes.get('white_value'))
|
||||
self.assertIsNone(state.attributes.get(ATTR_ASSUMED_STATE))
|
||||
|
||||
# Turn on the light
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb',
|
||||
'{"state":"ON",'
|
||||
'"color":{"r":255,"g":255,"b":255},'
|
||||
'"brightness": 255}')
|
||||
'"brightness": 255,'
|
||||
'"white_value": 255}')
|
||||
self.hass.block_till_done()
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_ON, state.state)
|
||||
self.assertEqual([255, 255, 255], state.attributes.get('rgb_color'))
|
||||
self.assertEqual(255, state.attributes.get('brightness'))
|
||||
self.assertEqual(255, state.attributes.get('white_value'))
|
||||
|
||||
# Bad color values
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb',
|
||||
|
@ -337,3 +458,14 @@ class TestLightMQTTJSON(unittest.TestCase):
|
|||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_ON, state.state)
|
||||
self.assertEqual(255, state.attributes.get('brightness'))
|
||||
|
||||
# Bad white value
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb',
|
||||
'{"state":"ON",'
|
||||
'"white_value": "badValue"}')
|
||||
self.hass.block_till_done()
|
||||
|
||||
# White value should not have changed
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_ON, state.state)
|
||||
self.assertEqual(255, state.attributes.get('white_value'))
|
||||
|
|
|
@ -12,13 +12,19 @@ light:
|
|||
command_off_template: 'off'
|
||||
state_template: '{{ value.split(",")[0] }}'
|
||||
brightness_template: '{{ value.split(",")[1] }}'
|
||||
red_template: '{{ value.split(",")[2].split("-")[0] }}'
|
||||
green_template: '{{ value.split(",")[2].split("-")[1] }}'
|
||||
blue_template: '{{ value.split(",")[2].split("-")[2] }}'
|
||||
color_temp_template: '{{ value.split(",")[2] }}'
|
||||
white_value_template: '{{ value.split(",")[3] }}'
|
||||
red_template: '{{ value.split(",")[4].split("-")[0] }}'
|
||||
green_template: '{{ value.split(",")[4].split("-")[1] }}'
|
||||
blue_template: '{{ value.split(",")[4].split("-")[2] }}'
|
||||
|
||||
If your light doesn't support brightness feature, omit `brightness_template`.
|
||||
|
||||
If your light doesn't support rgb feature, omit `(red|green|blue)_template`.
|
||||
If your light doesn't support color temp feature, omit `color_temp_template`.
|
||||
|
||||
If your light doesn't support white value feature, omit `white_value_template`.
|
||||
|
||||
If your light doesn't support RGB feature, omit `(red|green|blue)_template`.
|
||||
"""
|
||||
import unittest
|
||||
|
||||
|
@ -66,6 +72,8 @@ class TestLightMQTTTemplate(unittest.TestCase):
|
|||
'command_topic': 'test_light_rgb/set',
|
||||
'command_on_template': 'on,'
|
||||
'{{ brightness|d }},'
|
||||
'{{ color_temp|d }},'
|
||||
'{{ white_value|d }},'
|
||||
'{{ red|d }}-'
|
||||
'{{ green|d }}-'
|
||||
'{{ blue|d }}',
|
||||
|
@ -78,6 +86,8 @@ class TestLightMQTTTemplate(unittest.TestCase):
|
|||
self.assertEqual(STATE_OFF, state.state)
|
||||
self.assertIsNone(state.attributes.get('rgb_color'))
|
||||
self.assertIsNone(state.attributes.get('brightness'))
|
||||
self.assertIsNone(state.attributes.get('color_temp'))
|
||||
self.assertIsNone(state.attributes.get('white_value'))
|
||||
self.assertIsNone(state.attributes.get(ATTR_ASSUMED_STATE))
|
||||
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb', 'on')
|
||||
|
@ -87,10 +97,12 @@ class TestLightMQTTTemplate(unittest.TestCase):
|
|||
self.assertEqual(STATE_ON, state.state)
|
||||
self.assertIsNone(state.attributes.get('rgb_color'))
|
||||
self.assertIsNone(state.attributes.get('brightness'))
|
||||
self.assertIsNone(state.attributes.get('color_temp'))
|
||||
self.assertIsNone(state.attributes.get('white_value'))
|
||||
|
||||
def test_state_brightness_color_effect_change_via_topic(self): \
|
||||
def test_state_brightness_color_effect_temp_white_change_via_topic(self): \
|
||||
# pylint: disable=invalid-name
|
||||
"""Test state, brightness, color and effect change via topic."""
|
||||
"""Test state, bri, color, effect, color temp, white val change."""
|
||||
with assert_setup_component(1):
|
||||
assert setup_component(self.hass, light.DOMAIN, {
|
||||
light.DOMAIN: {
|
||||
|
@ -101,6 +113,8 @@ class TestLightMQTTTemplate(unittest.TestCase):
|
|||
'command_topic': 'test_light_rgb/set',
|
||||
'command_on_template': 'on,'
|
||||
'{{ brightness|d }},'
|
||||
'{{ color_temp|d }},'
|
||||
'{{ white_value|d }},'
|
||||
'{{ red|d }}-'
|
||||
'{{ green|d }}-'
|
||||
'{{ blue|d }},'
|
||||
|
@ -108,13 +122,15 @@ class TestLightMQTTTemplate(unittest.TestCase):
|
|||
'command_off_template': 'off',
|
||||
'state_template': '{{ value.split(",")[0] }}',
|
||||
'brightness_template': '{{ value.split(",")[1] }}',
|
||||
'red_template': '{{ value.split(",")[2].'
|
||||
'color_temp_template': '{{ value.split(",")[2] }}',
|
||||
'white_value_template': '{{ value.split(",")[3] }}',
|
||||
'red_template': '{{ value.split(",")[4].'
|
||||
'split("-")[0] }}',
|
||||
'green_template': '{{ value.split(",")[2].'
|
||||
'green_template': '{{ value.split(",")[4].'
|
||||
'split("-")[1] }}',
|
||||
'blue_template': '{{ value.split(",")[2].'
|
||||
'blue_template': '{{ value.split(",")[4].'
|
||||
'split("-")[2] }}',
|
||||
'effect_template': '{{ value.split(",")[3] }}'
|
||||
'effect_template': '{{ value.split(",")[5] }}'
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -123,16 +139,21 @@ class TestLightMQTTTemplate(unittest.TestCase):
|
|||
self.assertIsNone(state.attributes.get('rgb_color'))
|
||||
self.assertIsNone(state.attributes.get('brightness'))
|
||||
self.assertIsNone(state.attributes.get('effect'))
|
||||
self.assertIsNone(state.attributes.get('color_temp'))
|
||||
self.assertIsNone(state.attributes.get('white_value'))
|
||||
self.assertIsNone(state.attributes.get(ATTR_ASSUMED_STATE))
|
||||
|
||||
# turn on the light, full white
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb', 'on,255,255-255-255,')
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb',
|
||||
'on,255,145,123,255-255-255,')
|
||||
self.hass.block_till_done()
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_ON, state.state)
|
||||
self.assertEqual([255, 255, 255], state.attributes.get('rgb_color'))
|
||||
self.assertEqual(255, state.attributes.get('brightness'))
|
||||
self.assertEqual(145, state.attributes.get('color_temp'))
|
||||
self.assertEqual(123, state.attributes.get('white_value'))
|
||||
self.assertIsNone(state.attributes.get('effect'))
|
||||
|
||||
# turn the light off
|
||||
|
@ -150,15 +171,32 @@ class TestLightMQTTTemplate(unittest.TestCase):
|
|||
self.hass.block_till_done()
|
||||
self.assertEqual(100, light_state.attributes['brightness'])
|
||||
|
||||
# change the color temp
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb', 'on,,195')
|
||||
self.hass.block_till_done()
|
||||
|
||||
light_state = self.hass.states.get('light.test')
|
||||
self.hass.block_till_done()
|
||||
self.assertEqual(195, light_state.attributes['color_temp'])
|
||||
|
||||
# change the color
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb', 'on,,41-42-43')
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb', 'on,,,,41-42-43')
|
||||
self.hass.block_till_done()
|
||||
|
||||
light_state = self.hass.states.get('light.test')
|
||||
self.assertEqual([41, 42, 43], light_state.attributes.get('rgb_color'))
|
||||
|
||||
# change the white value
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb', 'on,,,134')
|
||||
self.hass.block_till_done()
|
||||
|
||||
light_state = self.hass.states.get('light.test')
|
||||
self.hass.block_till_done()
|
||||
self.assertEqual(134, light_state.attributes['white_value'])
|
||||
|
||||
# change the effect
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb', 'on,,41-42-43,rainbow')
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb',
|
||||
'on,,,,41-42-43,rainbow')
|
||||
self.hass.block_till_done()
|
||||
|
||||
light_state = self.hass.states.get('light.test')
|
||||
|
@ -175,6 +213,8 @@ class TestLightMQTTTemplate(unittest.TestCase):
|
|||
'command_topic': 'test_light_rgb/set',
|
||||
'command_on_template': 'on,'
|
||||
'{{ brightness|d }},'
|
||||
'{{ color_temp|d }},'
|
||||
'{{ white_value|d }},'
|
||||
'{{ red|d }}-'
|
||||
'{{ green|d }}-'
|
||||
'{{ blue|d }}',
|
||||
|
@ -191,7 +231,7 @@ class TestLightMQTTTemplate(unittest.TestCase):
|
|||
light.turn_on(self.hass, 'light.test')
|
||||
self.hass.block_till_done()
|
||||
|
||||
self.assertEqual(('test_light_rgb/set', 'on,,--', 2, False),
|
||||
self.assertEqual(('test_light_rgb/set', 'on,,,,--', 2, False),
|
||||
self.mock_publish.mock_calls[-2][1])
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_ON, state.state)
|
||||
|
@ -205,9 +245,9 @@ class TestLightMQTTTemplate(unittest.TestCase):
|
|||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_OFF, state.state)
|
||||
|
||||
# turn on the light with brightness and color
|
||||
# turn on the light with brightness, color, color temp and white val
|
||||
light.turn_on(self.hass, 'light.test', brightness=50,
|
||||
rgb_color=[75, 75, 75])
|
||||
rgb_color=[75, 75, 75], color_temp=200, white_value=139)
|
||||
self.hass.block_till_done()
|
||||
|
||||
self.assertEqual('test_light_rgb/set',
|
||||
|
@ -217,13 +257,15 @@ class TestLightMQTTTemplate(unittest.TestCase):
|
|||
|
||||
# check the payload
|
||||
payload = self.mock_publish.mock_calls[-2][1][1]
|
||||
self.assertEqual('on,50,75-75-75', payload)
|
||||
self.assertEqual('on,50,200,139,75-75-75', payload)
|
||||
|
||||
# check the state
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_ON, state.state)
|
||||
self.assertEqual((75, 75, 75), state.attributes['rgb_color'])
|
||||
self.assertEqual(50, state.attributes['brightness'])
|
||||
self.assertEqual(200, state.attributes['color_temp'])
|
||||
self.assertEqual(139, state.attributes['white_value'])
|
||||
|
||||
def test_flash(self): \
|
||||
# pylint: disable=invalid-name
|
||||
|
@ -324,6 +366,7 @@ class TestLightMQTTTemplate(unittest.TestCase):
|
|||
'command_topic': 'test_light_rgb/set',
|
||||
'command_on_template': 'on,'
|
||||
'{{ brightness|d }},'
|
||||
'{{ color_temp|d }},'
|
||||
'{{ red|d }}-'
|
||||
'{{ green|d }}-'
|
||||
'{{ blue|d }},'
|
||||
|
@ -331,13 +374,15 @@ class TestLightMQTTTemplate(unittest.TestCase):
|
|||
'command_off_template': 'off',
|
||||
'state_template': '{{ value.split(",")[0] }}',
|
||||
'brightness_template': '{{ value.split(",")[1] }}',
|
||||
'red_template': '{{ value.split(",")[2].'
|
||||
'color_temp_template': '{{ value.split(",")[2] }}',
|
||||
'white_value_template': '{{ value.split(",")[3] }}',
|
||||
'red_template': '{{ value.split(",")[4].'
|
||||
'split("-")[0] }}',
|
||||
'green_template': '{{ value.split(",")[2].'
|
||||
'green_template': '{{ value.split(",")[4].'
|
||||
'split("-")[1] }}',
|
||||
'blue_template': '{{ value.split(",")[2].'
|
||||
'blue_template': '{{ value.split(",")[4].'
|
||||
'split("-")[2] }}',
|
||||
'effect_template': '{{ value.split(",")[3] }}',
|
||||
'effect_template': '{{ value.split(",")[5] }}',
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -345,18 +390,22 @@ class TestLightMQTTTemplate(unittest.TestCase):
|
|||
self.assertEqual(STATE_OFF, state.state)
|
||||
self.assertIsNone(state.attributes.get('rgb_color'))
|
||||
self.assertIsNone(state.attributes.get('brightness'))
|
||||
self.assertIsNone(state.attributes.get('color_temp'))
|
||||
self.assertIsNone(state.attributes.get('effect'))
|
||||
self.assertIsNone(state.attributes.get('white_value'))
|
||||
self.assertIsNone(state.attributes.get(ATTR_ASSUMED_STATE))
|
||||
|
||||
# turn on the light, full white
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb',
|
||||
'on,255,255-255-255,rainbow')
|
||||
'on,255,215,222,255-255-255,rainbow')
|
||||
self.hass.block_till_done()
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_ON, state.state)
|
||||
self.assertEqual(255, state.attributes.get('brightness'))
|
||||
self.assertEqual(215, state.attributes.get('color_temp'))
|
||||
self.assertEqual([255, 255, 255], state.attributes.get('rgb_color'))
|
||||
self.assertEqual(222, state.attributes.get('white_value'))
|
||||
self.assertEqual('rainbow', state.attributes.get('effect'))
|
||||
|
||||
# bad state value
|
||||
|
@ -375,6 +424,14 @@ class TestLightMQTTTemplate(unittest.TestCase):
|
|||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(255, state.attributes.get('brightness'))
|
||||
|
||||
# bad color temp values
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb', 'on,,off,255-255-255')
|
||||
self.hass.block_till_done()
|
||||
|
||||
# color temp should not have changed
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(215, state.attributes.get('color_temp'))
|
||||
|
||||
# bad color values
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb', 'on,255,a-b-c')
|
||||
self.hass.block_till_done()
|
||||
|
@ -383,6 +440,14 @@ class TestLightMQTTTemplate(unittest.TestCase):
|
|||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual([255, 255, 255], state.attributes.get('rgb_color'))
|
||||
|
||||
# bad white value values
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb', 'on,,,off,255-255-255')
|
||||
self.hass.block_till_done()
|
||||
|
||||
# white value should not have changed
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(222, state.attributes.get('white_value'))
|
||||
|
||||
# bad effect value
|
||||
fire_mqtt_message(self.hass, 'test_light_rgb', 'on,255,a-b-c,white')
|
||||
self.hass.block_till_done()
|
||||
|
|
Loading…
Reference in New Issue