Use dict[key] for required config keys and keys with default values of MQTT light (#22834)

* Use dict[key] for required config keys and keys with default values.

* Improve tests

* Lint

* Improve tests of JSON data
This commit is contained in:
Erik Montnemery 2019-04-10 11:16:41 +02:00 committed by Fabian Affolter
parent bbedf091aa
commit bc5f0ff0b3
4 changed files with 357 additions and 85 deletions

View File

@ -81,6 +81,7 @@ PLATFORM_SCHEMA_BASIC = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_COLOR_TEMP_COMMAND_TOPIC): mqtt.valid_publish_topic, 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_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_COLOR_TEMP_VALUE_TEMPLATE): cv.template, vol.Optional(CONF_COLOR_TEMP_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_DEVICE): mqtt.MQTT_ENTITY_DEVICE_INFO_SCHEMA,
vol.Optional(CONF_EFFECT_COMMAND_TOPIC): mqtt.valid_publish_topic, 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_LIST): vol.All(cv.ensure_list, [cv.string]),
vol.Optional(CONF_EFFECT_STATE_TOPIC): mqtt.valid_subscribe_topic, vol.Optional(CONF_EFFECT_STATE_TOPIC): mqtt.valid_subscribe_topic,
@ -89,7 +90,8 @@ PLATFORM_SCHEMA_BASIC = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_HS_STATE_TOPIC): mqtt.valid_subscribe_topic, vol.Optional(CONF_HS_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_HS_VALUE_TEMPLATE): cv.template, vol.Optional(CONF_HS_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_UNIQUE_ID): cv.string, vol.Optional(CONF_ON_COMMAND_TYPE, default=DEFAULT_ON_COMMAND_TYPE):
vol.In(VALUES_ON_COMMAND_TYPE),
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean, vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
vol.Optional(CONF_PAYLOAD_OFF, default=DEFAULT_PAYLOAD_OFF): cv.string, 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_PAYLOAD_ON, default=DEFAULT_PAYLOAD_ON): cv.string,
@ -98,6 +100,7 @@ PLATFORM_SCHEMA_BASIC = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_RGB_STATE_TOPIC): mqtt.valid_subscribe_topic, vol.Optional(CONF_RGB_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_RGB_VALUE_TEMPLATE): cv.template, vol.Optional(CONF_RGB_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_STATE_VALUE_TEMPLATE): cv.template, vol.Optional(CONF_STATE_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_UNIQUE_ID): cv.string,
vol.Optional(CONF_WHITE_VALUE_COMMAND_TOPIC): mqtt.valid_publish_topic, vol.Optional(CONF_WHITE_VALUE_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_WHITE_VALUE_SCALE, default=DEFAULT_WHITE_VALUE_SCALE): vol.Optional(CONF_WHITE_VALUE_SCALE, default=DEFAULT_WHITE_VALUE_SCALE):
vol.All(vol.Coerce(int), vol.Range(min=1)), vol.All(vol.Coerce(int), vol.Range(min=1)),
@ -106,9 +109,6 @@ PLATFORM_SCHEMA_BASIC = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_XY_COMMAND_TOPIC): mqtt.valid_publish_topic, vol.Optional(CONF_XY_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_XY_STATE_TOPIC): mqtt.valid_subscribe_topic, vol.Optional(CONF_XY_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_XY_VALUE_TEMPLATE): cv.template, vol.Optional(CONF_XY_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_ON_COMMAND_TYPE, default=DEFAULT_ON_COMMAND_TYPE):
vol.In(VALUES_ON_COMMAND_TYPE),
vol.Optional(CONF_DEVICE): mqtt.MQTT_ENTITY_DEVICE_INFO_SCHEMA,
}).extend(mqtt.MQTT_AVAILABILITY_SCHEMA.schema).extend( }).extend(mqtt.MQTT_AVAILABILITY_SCHEMA.schema).extend(
mqtt.MQTT_JSON_ATTRS_SCHEMA.schema).extend(MQTT_LIGHT_SCHEMA_SCHEMA.schema) mqtt.MQTT_JSON_ATTRS_SCHEMA.schema).extend(MQTT_LIGHT_SCHEMA_SCHEMA.schema)
@ -202,8 +202,8 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
} }
self._topic = topic self._topic = topic
self._payload = { self._payload = {
'on': config.get(CONF_PAYLOAD_ON), 'on': config[CONF_PAYLOAD_ON],
'off': config.get(CONF_PAYLOAD_OFF), 'off': config[CONF_PAYLOAD_OFF],
} }
self._templates = { self._templates = {
CONF_BRIGHTNESS: config.get(CONF_BRIGHTNESS_VALUE_TEMPLATE), CONF_BRIGHTNESS: config.get(CONF_BRIGHTNESS_VALUE_TEMPLATE),
@ -219,7 +219,7 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
CONF_XY: config.get(CONF_XY_VALUE_TEMPLATE), CONF_XY: config.get(CONF_XY_VALUE_TEMPLATE),
} }
optimistic = config.get(CONF_OPTIMISTIC) optimistic = config[CONF_OPTIMISTIC]
self._optimistic = optimistic or topic[CONF_STATE_TOPIC] is None self._optimistic = optimistic or topic[CONF_STATE_TOPIC] is None
self._optimistic_rgb = \ self._optimistic_rgb = \
optimistic or topic[CONF_RGB_STATE_TOPIC] is None optimistic or topic[CONF_RGB_STATE_TOPIC] is None
@ -272,7 +272,7 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
topics[CONF_STATE_TOPIC] = { topics[CONF_STATE_TOPIC] = {
'topic': self._topic[CONF_STATE_TOPIC], 'topic': self._topic[CONF_STATE_TOPIC],
'msg_callback': state_received, 'msg_callback': state_received,
'qos': self._config.get(CONF_QOS)} 'qos': self._config[CONF_QOS]}
elif self._optimistic and last_state: elif self._optimistic and last_state:
self._state = last_state.state == STATE_ON self._state = last_state.state == STATE_ON
@ -287,7 +287,7 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
device_value = float(payload) device_value = float(payload)
percent_bright = \ percent_bright = \
device_value / self._config.get(CONF_BRIGHTNESS_SCALE) device_value / self._config[CONF_BRIGHTNESS_SCALE]
self._brightness = percent_bright * 255 self._brightness = percent_bright * 255
self.async_write_ha_state() self.async_write_ha_state()
@ -295,7 +295,7 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
topics[CONF_BRIGHTNESS_STATE_TOPIC] = { topics[CONF_BRIGHTNESS_STATE_TOPIC] = {
'topic': self._topic[CONF_BRIGHTNESS_STATE_TOPIC], 'topic': self._topic[CONF_BRIGHTNESS_STATE_TOPIC],
'msg_callback': brightness_received, 'msg_callback': brightness_received,
'qos': self._config.get(CONF_QOS)} 'qos': self._config[CONF_QOS]}
self._brightness = 255 self._brightness = 255
elif self._optimistic_brightness and last_state\ elif self._optimistic_brightness and last_state\
and last_state.attributes.get(ATTR_BRIGHTNESS): and last_state.attributes.get(ATTR_BRIGHTNESS):
@ -326,7 +326,7 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
topics[CONF_RGB_STATE_TOPIC] = { topics[CONF_RGB_STATE_TOPIC] = {
'topic': self._topic[CONF_RGB_STATE_TOPIC], 'topic': self._topic[CONF_RGB_STATE_TOPIC],
'msg_callback': rgb_received, 'msg_callback': rgb_received,
'qos': self._config.get(CONF_QOS)} 'qos': self._config[CONF_QOS]}
self._hs = (0, 0) self._hs = (0, 0)
if self._optimistic_rgb and last_state\ if self._optimistic_rgb and last_state\
and last_state.attributes.get(ATTR_HS_COLOR): and last_state.attributes.get(ATTR_HS_COLOR):
@ -350,7 +350,7 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
topics[CONF_COLOR_TEMP_STATE_TOPIC] = { topics[CONF_COLOR_TEMP_STATE_TOPIC] = {
'topic': self._topic[CONF_COLOR_TEMP_STATE_TOPIC], 'topic': self._topic[CONF_COLOR_TEMP_STATE_TOPIC],
'msg_callback': color_temp_received, 'msg_callback': color_temp_received,
'qos': self._config.get(CONF_QOS)} 'qos': self._config[CONF_QOS]}
self._color_temp = 150 self._color_temp = 150
if self._optimistic_color_temp and last_state\ if self._optimistic_color_temp and last_state\
and last_state.attributes.get(ATTR_COLOR_TEMP): and last_state.attributes.get(ATTR_COLOR_TEMP):
@ -376,7 +376,7 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
topics[CONF_EFFECT_STATE_TOPIC] = { topics[CONF_EFFECT_STATE_TOPIC] = {
'topic': self._topic[CONF_EFFECT_STATE_TOPIC], 'topic': self._topic[CONF_EFFECT_STATE_TOPIC],
'msg_callback': effect_received, 'msg_callback': effect_received,
'qos': self._config.get(CONF_QOS)} 'qos': self._config[CONF_QOS]}
self._effect = 'none' self._effect = 'none'
if self._optimistic_effect and last_state\ if self._optimistic_effect and last_state\
and last_state.attributes.get(ATTR_EFFECT): and last_state.attributes.get(ATTR_EFFECT):
@ -406,7 +406,7 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
topics[CONF_HS_STATE_TOPIC] = { topics[CONF_HS_STATE_TOPIC] = {
'topic': self._topic[CONF_HS_STATE_TOPIC], 'topic': self._topic[CONF_HS_STATE_TOPIC],
'msg_callback': hs_received, 'msg_callback': hs_received,
'qos': self._config.get(CONF_QOS)} 'qos': self._config[CONF_QOS]}
self._hs = (0, 0) self._hs = (0, 0)
if self._optimistic_hs and last_state\ if self._optimistic_hs and last_state\
and last_state.attributes.get(ATTR_HS_COLOR): and last_state.attributes.get(ATTR_HS_COLOR):
@ -425,7 +425,7 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
device_value = float(payload) device_value = float(payload)
percent_white = \ percent_white = \
device_value / self._config.get(CONF_WHITE_VALUE_SCALE) device_value / self._config[CONF_WHITE_VALUE_SCALE]
self._white_value = percent_white * 255 self._white_value = percent_white * 255
self.async_write_ha_state() self.async_write_ha_state()
@ -433,7 +433,7 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
topics[CONF_WHITE_VALUE_STATE_TOPIC] = { topics[CONF_WHITE_VALUE_STATE_TOPIC] = {
'topic': self._topic[CONF_WHITE_VALUE_STATE_TOPIC], 'topic': self._topic[CONF_WHITE_VALUE_STATE_TOPIC],
'msg_callback': white_value_received, 'msg_callback': white_value_received,
'qos': self._config.get(CONF_QOS)} 'qos': self._config[CONF_QOS]}
self._white_value = 255 self._white_value = 255
elif self._optimistic_white_value and last_state\ elif self._optimistic_white_value and last_state\
and last_state.attributes.get(ATTR_WHITE_VALUE): and last_state.attributes.get(ATTR_WHITE_VALUE):
@ -460,7 +460,7 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
topics[CONF_XY_STATE_TOPIC] = { topics[CONF_XY_STATE_TOPIC] = {
'topic': self._topic[CONF_XY_STATE_TOPIC], 'topic': self._topic[CONF_XY_STATE_TOPIC],
'msg_callback': xy_received, 'msg_callback': xy_received,
'qos': self._config.get(CONF_QOS)} 'qos': self._config[CONF_QOS]}
self._hs = (0, 0) self._hs = (0, 0)
if self._optimistic_xy and last_state\ if self._optimistic_xy and last_state\
and last_state.attributes.get(ATTR_HS_COLOR): and last_state.attributes.get(ATTR_HS_COLOR):
@ -513,7 +513,7 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
@property @property
def name(self): def name(self):
"""Return the name of the device if any.""" """Return the name of the device if any."""
return self._config.get(CONF_NAME) return self._config[CONF_NAME]
@property @property
def unique_id(self): def unique_id(self):
@ -572,13 +572,13 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
This method is a coroutine. This method is a coroutine.
""" """
should_update = False should_update = False
on_command_type = self._config.get(CONF_ON_COMMAND_TYPE) on_command_type = self._config[CONF_ON_COMMAND_TYPE]
if on_command_type == 'first': if on_command_type == 'first':
mqtt.async_publish( mqtt.async_publish(
self.hass, self._topic[CONF_COMMAND_TOPIC], self.hass, self._topic[CONF_COMMAND_TOPIC],
self._payload['on'], self._config.get(CONF_QOS), self._payload['on'], self._config[CONF_QOS],
self._config.get(CONF_RETAIN)) self._config[CONF_RETAIN])
should_update = True should_update = True
# If brightness is being used instead of an on command, make sure # If brightness is being used instead of an on command, make sure
@ -616,8 +616,8 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
mqtt.async_publish( mqtt.async_publish(
self.hass, self._topic[CONF_RGB_COMMAND_TOPIC], self.hass, self._topic[CONF_RGB_COMMAND_TOPIC],
rgb_color_str, self._config.get(CONF_QOS), rgb_color_str, self._config[CONF_QOS],
self._config.get(CONF_RETAIN)) self._config[CONF_RETAIN])
if self._optimistic_rgb: if self._optimistic_rgb:
self._hs = kwargs[ATTR_HS_COLOR] self._hs = kwargs[ATTR_HS_COLOR]
@ -629,8 +629,8 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
hs_color = kwargs[ATTR_HS_COLOR] hs_color = kwargs[ATTR_HS_COLOR]
mqtt.async_publish( mqtt.async_publish(
self.hass, self._topic[CONF_HS_COMMAND_TOPIC], self.hass, self._topic[CONF_HS_COMMAND_TOPIC],
'{},{}'.format(*hs_color), self._config.get(CONF_QOS), '{},{}'.format(*hs_color), self._config[CONF_QOS],
self._config.get(CONF_RETAIN)) self._config[CONF_RETAIN])
if self._optimistic_hs: if self._optimistic_hs:
self._hs = kwargs[ATTR_HS_COLOR] self._hs = kwargs[ATTR_HS_COLOR]
@ -642,8 +642,8 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
xy_color = color_util.color_hs_to_xy(*kwargs[ATTR_HS_COLOR]) xy_color = color_util.color_hs_to_xy(*kwargs[ATTR_HS_COLOR])
mqtt.async_publish( mqtt.async_publish(
self.hass, self._topic[CONF_XY_COMMAND_TOPIC], self.hass, self._topic[CONF_XY_COMMAND_TOPIC],
'{},{}'.format(*xy_color), self._config.get(CONF_QOS), '{},{}'.format(*xy_color), self._config[CONF_QOS],
self._config.get(CONF_RETAIN)) self._config[CONF_RETAIN])
if self._optimistic_xy: if self._optimistic_xy:
self._hs = kwargs[ATTR_HS_COLOR] self._hs = kwargs[ATTR_HS_COLOR]
@ -652,13 +652,13 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
if ATTR_BRIGHTNESS in kwargs and \ if ATTR_BRIGHTNESS in kwargs and \
self._topic[CONF_BRIGHTNESS_COMMAND_TOPIC] is not None: self._topic[CONF_BRIGHTNESS_COMMAND_TOPIC] is not None:
percent_bright = float(kwargs[ATTR_BRIGHTNESS]) / 255 percent_bright = float(kwargs[ATTR_BRIGHTNESS]) / 255
brightness_scale = self._config.get(CONF_BRIGHTNESS_SCALE) brightness_scale = self._config[CONF_BRIGHTNESS_SCALE]
device_brightness = \ device_brightness = \
min(round(percent_bright * brightness_scale), brightness_scale) min(round(percent_bright * brightness_scale), brightness_scale)
mqtt.async_publish( mqtt.async_publish(
self.hass, self._topic[CONF_BRIGHTNESS_COMMAND_TOPIC], self.hass, self._topic[CONF_BRIGHTNESS_COMMAND_TOPIC],
device_brightness, self._config.get(CONF_QOS), device_brightness, self._config[CONF_QOS],
self._config.get(CONF_RETAIN)) self._config[CONF_RETAIN])
if self._optimistic_brightness: if self._optimistic_brightness:
self._brightness = kwargs[ATTR_BRIGHTNESS] self._brightness = kwargs[ATTR_BRIGHTNESS]
@ -679,8 +679,8 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
mqtt.async_publish( mqtt.async_publish(
self.hass, self._topic[CONF_RGB_COMMAND_TOPIC], self.hass, self._topic[CONF_RGB_COMMAND_TOPIC],
rgb_color_str, self._config.get(CONF_QOS), rgb_color_str, self._config[CONF_QOS],
self._config.get(CONF_RETAIN)) self._config[CONF_RETAIN])
if self._optimistic_brightness: if self._optimistic_brightness:
self._brightness = kwargs[ATTR_BRIGHTNESS] self._brightness = kwargs[ATTR_BRIGHTNESS]
@ -698,8 +698,8 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
mqtt.async_publish( mqtt.async_publish(
self.hass, self._topic[CONF_COLOR_TEMP_COMMAND_TOPIC], self.hass, self._topic[CONF_COLOR_TEMP_COMMAND_TOPIC],
color_temp, self._config.get(CONF_QOS), color_temp, self._config[CONF_QOS],
self._config.get(CONF_RETAIN)) self._config[CONF_RETAIN])
if self._optimistic_color_temp: if self._optimistic_color_temp:
self._color_temp = kwargs[ATTR_COLOR_TEMP] self._color_temp = kwargs[ATTR_COLOR_TEMP]
@ -711,8 +711,8 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
if effect in self._config.get(CONF_EFFECT_LIST): if effect in self._config.get(CONF_EFFECT_LIST):
mqtt.async_publish( mqtt.async_publish(
self.hass, self._topic[CONF_EFFECT_COMMAND_TOPIC], self.hass, self._topic[CONF_EFFECT_COMMAND_TOPIC],
effect, self._config.get(CONF_QOS), effect, self._config[CONF_QOS],
self._config.get(CONF_RETAIN)) self._config[CONF_RETAIN])
if self._optimistic_effect: if self._optimistic_effect:
self._effect = kwargs[ATTR_EFFECT] self._effect = kwargs[ATTR_EFFECT]
@ -721,13 +721,13 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
if ATTR_WHITE_VALUE in kwargs and \ if ATTR_WHITE_VALUE in kwargs and \
self._topic[CONF_WHITE_VALUE_COMMAND_TOPIC] is not None: self._topic[CONF_WHITE_VALUE_COMMAND_TOPIC] is not None:
percent_white = float(kwargs[ATTR_WHITE_VALUE]) / 255 percent_white = float(kwargs[ATTR_WHITE_VALUE]) / 255
white_scale = self._config.get(CONF_WHITE_VALUE_SCALE) white_scale = self._config[CONF_WHITE_VALUE_SCALE]
device_white_value = \ device_white_value = \
min(round(percent_white * white_scale), white_scale) min(round(percent_white * white_scale), white_scale)
mqtt.async_publish( mqtt.async_publish(
self.hass, self._topic[CONF_WHITE_VALUE_COMMAND_TOPIC], self.hass, self._topic[CONF_WHITE_VALUE_COMMAND_TOPIC],
device_white_value, self._config.get(CONF_QOS), device_white_value, self._config[CONF_QOS],
self._config.get(CONF_RETAIN)) self._config[CONF_RETAIN])
if self._optimistic_white_value: if self._optimistic_white_value:
self._white_value = kwargs[ATTR_WHITE_VALUE] self._white_value = kwargs[ATTR_WHITE_VALUE]
@ -735,8 +735,8 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
if on_command_type == 'last': if on_command_type == 'last':
mqtt.async_publish(self.hass, self._topic[CONF_COMMAND_TOPIC], mqtt.async_publish(self.hass, self._topic[CONF_COMMAND_TOPIC],
self._payload['on'], self._config.get(CONF_QOS), self._payload['on'], self._config[CONF_QOS],
self._config.get(CONF_RETAIN)) self._config[CONF_RETAIN])
should_update = True should_update = True
if self._optimistic: if self._optimistic:
@ -754,7 +754,7 @@ class MqttLight(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
""" """
mqtt.async_publish( mqtt.async_publish(
self.hass, self._topic[CONF_COMMAND_TOPIC], self._payload['off'], self.hass, self._topic[CONF_COMMAND_TOPIC], self._payload['off'],
self._config.get(CONF_QOS), self._config.get(CONF_RETAIN)) self._config[CONF_QOS], self._config[CONF_RETAIN])
if self._optimistic: if self._optimistic:
# Optimistically assume that the light has changed state. # Optimistically assume that the light has changed state.

View File

@ -62,25 +62,24 @@ PLATFORM_SCHEMA_JSON = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_BRIGHTNESS_SCALE, default=DEFAULT_BRIGHTNESS_SCALE): vol.Optional(CONF_BRIGHTNESS_SCALE, default=DEFAULT_BRIGHTNESS_SCALE):
vol.All(vol.Coerce(int), vol.Range(min=1)), vol.All(vol.Coerce(int), vol.Range(min=1)),
vol.Optional(CONF_COLOR_TEMP, default=DEFAULT_COLOR_TEMP): cv.boolean, vol.Optional(CONF_COLOR_TEMP, default=DEFAULT_COLOR_TEMP): cv.boolean,
vol.Optional(CONF_DEVICE): mqtt.MQTT_ENTITY_DEVICE_INFO_SCHEMA,
vol.Optional(CONF_EFFECT, default=DEFAULT_EFFECT): 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_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): vol.Optional(CONF_FLASH_TIME_LONG, default=DEFAULT_FLASH_TIME_LONG):
cv.positive_int, cv.positive_int,
vol.Optional(CONF_FLASH_TIME_SHORT, default=DEFAULT_FLASH_TIME_SHORT):
cv.positive_int,
vol.Optional(CONF_HS, default=DEFAULT_HS): cv.boolean,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_UNIQUE_ID): cv.string,
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean, vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
vol.Optional(CONF_QOS, default=mqtt.DEFAULT_QOS): vol.Optional(CONF_QOS, default=mqtt.DEFAULT_QOS):
vol.All(vol.Coerce(int), vol.In([0, 1, 2])), vol.All(vol.Coerce(int), vol.In([0, 1, 2])),
vol.Optional(CONF_RETAIN, default=mqtt.DEFAULT_RETAIN): cv.boolean, vol.Optional(CONF_RETAIN, default=mqtt.DEFAULT_RETAIN): cv.boolean,
vol.Optional(CONF_RGB, default=DEFAULT_RGB): cv.boolean, vol.Optional(CONF_RGB, default=DEFAULT_RGB): cv.boolean,
vol.Optional(CONF_STATE_TOPIC): mqtt.valid_subscribe_topic, vol.Optional(CONF_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_UNIQUE_ID): cv.string,
vol.Optional(CONF_WHITE_VALUE, default=DEFAULT_WHITE_VALUE): cv.boolean, vol.Optional(CONF_WHITE_VALUE, default=DEFAULT_WHITE_VALUE): cv.boolean,
vol.Optional(CONF_XY, default=DEFAULT_XY): cv.boolean, vol.Optional(CONF_XY, default=DEFAULT_XY): cv.boolean,
vol.Optional(CONF_HS, default=DEFAULT_HS): cv.boolean,
vol.Required(CONF_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_DEVICE): mqtt.MQTT_ENTITY_DEVICE_INFO_SCHEMA,
}).extend(mqtt.MQTT_AVAILABILITY_SCHEMA.schema).extend( }).extend(mqtt.MQTT_AVAILABILITY_SCHEMA.schema).extend(
mqtt.MQTT_JSON_ATTRS_SCHEMA.schema).extend(MQTT_LIGHT_SCHEMA_SCHEMA.schema) mqtt.MQTT_JSON_ATTRS_SCHEMA.schema).extend(MQTT_LIGHT_SCHEMA_SCHEMA.schema)
@ -148,34 +147,34 @@ class MqttLightJson(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
CONF_COMMAND_TOPIC CONF_COMMAND_TOPIC
) )
} }
optimistic = config.get(CONF_OPTIMISTIC) optimistic = config[CONF_OPTIMISTIC]
self._optimistic = optimistic or self._topic[CONF_STATE_TOPIC] is None self._optimistic = optimistic or self._topic[CONF_STATE_TOPIC] is None
brightness = config.get(CONF_BRIGHTNESS) brightness = config[CONF_BRIGHTNESS]
if brightness: if brightness:
self._brightness = 255 self._brightness = 255
else: else:
self._brightness = None self._brightness = None
color_temp = config.get(CONF_COLOR_TEMP) color_temp = config[CONF_COLOR_TEMP]
if color_temp: if color_temp:
self._color_temp = 150 self._color_temp = 150
else: else:
self._color_temp = None self._color_temp = None
effect = config.get(CONF_EFFECT) effect = config[CONF_EFFECT]
if effect: if effect:
self._effect = 'none' self._effect = 'none'
else: else:
self._effect = None self._effect = None
white_value = config.get(CONF_WHITE_VALUE) white_value = config[CONF_WHITE_VALUE]
if white_value: if white_value:
self._white_value = 255 self._white_value = 255
else: else:
self._white_value = None self._white_value = None
if config.get(CONF_HS) or config.get(CONF_RGB) or config.get(CONF_XY): if config[CONF_HS] or config[CONF_RGB] or config[CONF_XY]:
self._hs = [0, 0] self._hs = [0, 0]
else: else:
self._hs = None self._hs = None
@ -188,13 +187,13 @@ class MqttLightJson(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
} }
self._supported_features = (SUPPORT_TRANSITION | SUPPORT_FLASH) self._supported_features = (SUPPORT_TRANSITION | SUPPORT_FLASH)
self._supported_features |= (config.get(CONF_RGB) and SUPPORT_COLOR) self._supported_features |= (config[CONF_RGB] and SUPPORT_COLOR)
self._supported_features |= (brightness and SUPPORT_BRIGHTNESS) self._supported_features |= (brightness and SUPPORT_BRIGHTNESS)
self._supported_features |= (color_temp and SUPPORT_COLOR_TEMP) self._supported_features |= (color_temp and SUPPORT_COLOR_TEMP)
self._supported_features |= (effect and SUPPORT_EFFECT) self._supported_features |= (effect and SUPPORT_EFFECT)
self._supported_features |= (white_value and SUPPORT_WHITE_VALUE) self._supported_features |= (white_value and SUPPORT_WHITE_VALUE)
self._supported_features |= (config.get(CONF_XY) and SUPPORT_COLOR) self._supported_features |= (config[CONF_XY] and SUPPORT_COLOR)
self._supported_features |= (config.get(CONF_HS) and SUPPORT_COLOR) self._supported_features |= (config[CONF_HS] and SUPPORT_COLOR)
async def _subscribe_topics(self): async def _subscribe_topics(self):
"""(Re)Subscribe to topics.""" """(Re)Subscribe to topics."""
@ -246,7 +245,7 @@ class MqttLightJson(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
try: try:
self._brightness = int( self._brightness = int(
values['brightness'] / values['brightness'] /
float(self._config.get(CONF_BRIGHTNESS_SCALE)) * 255) float(self._config[CONF_BRIGHTNESS_SCALE]) * 255)
except KeyError: except KeyError:
pass pass
except ValueError: except ValueError:
@ -283,7 +282,7 @@ class MqttLightJson(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
self.hass, self._sub_state, self.hass, self._sub_state,
{'state_topic': {'topic': self._topic[CONF_STATE_TOPIC], {'state_topic': {'topic': self._topic[CONF_STATE_TOPIC],
'msg_callback': state_received, 'msg_callback': state_received,
'qos': self._config.get(CONF_QOS)}}) 'qos': self._config[CONF_QOS]}})
if self._optimistic and last_state: if self._optimistic and last_state:
self._state = last_state.state == STATE_ON self._state = last_state.state == STATE_ON
@ -343,7 +342,7 @@ class MqttLightJson(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
@property @property
def name(self): def name(self):
"""Return the name of the device if any.""" """Return the name of the device if any."""
return self._config.get(CONF_NAME) return self._config[CONF_NAME]
@property @property
def unique_id(self): def unique_id(self):
@ -375,11 +374,11 @@ class MqttLightJson(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
message = {'state': 'ON'} message = {'state': 'ON'}
if ATTR_HS_COLOR in kwargs and ( if ATTR_HS_COLOR in kwargs and (
self._config.get(CONF_HS) or self._config.get(CONF_RGB) self._config[CONF_HS] or self._config[CONF_RGB]
or self._config.get(CONF_XY)): or self._config[CONF_XY]):
hs_color = kwargs[ATTR_HS_COLOR] hs_color = kwargs[ATTR_HS_COLOR]
message['color'] = {} message['color'] = {}
if self._config.get(CONF_RGB): if self._config[CONF_RGB]:
# If there's a brightness topic set, we don't want to scale the # If there's a brightness topic set, we don't want to scale the
# RGB values given using the brightness. # RGB values given using the brightness.
if self._brightness is not None: if self._brightness is not None:
@ -393,11 +392,11 @@ class MqttLightJson(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
message['color']['r'] = rgb[0] message['color']['r'] = rgb[0]
message['color']['g'] = rgb[1] message['color']['g'] = rgb[1]
message['color']['b'] = rgb[2] message['color']['b'] = rgb[2]
if self._config.get(CONF_XY): if self._config[CONF_XY]:
xy_color = color_util.color_hs_to_xy(*kwargs[ATTR_HS_COLOR]) xy_color = color_util.color_hs_to_xy(*kwargs[ATTR_HS_COLOR])
message['color']['x'] = xy_color[0] message['color']['x'] = xy_color[0]
message['color']['y'] = xy_color[1] message['color']['y'] = xy_color[1]
if self._config.get(CONF_HS): if self._config[CONF_HS]:
message['color']['h'] = hs_color[0] message['color']['h'] = hs_color[0]
message['color']['s'] = hs_color[1] message['color']['s'] = hs_color[1]
@ -416,10 +415,10 @@ class MqttLightJson(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
if ATTR_TRANSITION in kwargs: if ATTR_TRANSITION in kwargs:
message['transition'] = int(kwargs[ATTR_TRANSITION]) message['transition'] = int(kwargs[ATTR_TRANSITION])
if ATTR_BRIGHTNESS in kwargs: if ATTR_BRIGHTNESS in kwargs and self._brightness is not None:
message['brightness'] = int( message['brightness'] = int(
kwargs[ATTR_BRIGHTNESS] / float(DEFAULT_BRIGHTNESS_SCALE) * kwargs[ATTR_BRIGHTNESS] / float(DEFAULT_BRIGHTNESS_SCALE) *
self._config.get(CONF_BRIGHTNESS_SCALE)) self._config[CONF_BRIGHTNESS_SCALE])
if self._optimistic: if self._optimistic:
self._brightness = kwargs[ATTR_BRIGHTNESS] self._brightness = kwargs[ATTR_BRIGHTNESS]
@ -448,7 +447,7 @@ class MqttLightJson(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
mqtt.async_publish( mqtt.async_publish(
self.hass, self._topic[CONF_COMMAND_TOPIC], json.dumps(message), self.hass, self._topic[CONF_COMMAND_TOPIC], json.dumps(message),
self._config.get(CONF_QOS), self._config.get(CONF_RETAIN)) self._config[CONF_QOS], self._config[CONF_RETAIN])
if self._optimistic: if self._optimistic:
# Optimistically assume that the light has changed state. # Optimistically assume that the light has changed state.
@ -470,7 +469,7 @@ class MqttLightJson(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
mqtt.async_publish( mqtt.async_publish(
self.hass, self._topic[CONF_COMMAND_TOPIC], json.dumps(message), self.hass, self._topic[CONF_COMMAND_TOPIC], json.dumps(message),
self._config.get(CONF_QOS), self._config.get(CONF_RETAIN)) self._config[CONF_QOS], self._config[CONF_RETAIN])
if self._optimistic: if self._optimistic:
# Optimistically assume that the light has changed state. # Optimistically assume that the light has changed state.

View File

@ -51,23 +51,18 @@ PLATFORM_SCHEMA_TEMPLATE = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_BLUE_TEMPLATE): cv.template, vol.Optional(CONF_BLUE_TEMPLATE): cv.template,
vol.Optional(CONF_BRIGHTNESS_TEMPLATE): cv.template, vol.Optional(CONF_BRIGHTNESS_TEMPLATE): cv.template,
vol.Optional(CONF_COLOR_TEMP_TEMPLATE): cv.template, vol.Optional(CONF_COLOR_TEMP_TEMPLATE): cv.template,
vol.Required(CONF_COMMAND_OFF_TEMPLATE): cv.template,
vol.Required(CONF_COMMAND_ON_TEMPLATE): cv.template,
vol.Optional(CONF_DEVICE): mqtt.MQTT_ENTITY_DEVICE_INFO_SCHEMA,
vol.Optional(CONF_EFFECT_LIST): vol.All(cv.ensure_list, [cv.string]), vol.Optional(CONF_EFFECT_LIST): vol.All(cv.ensure_list, [cv.string]),
vol.Optional(CONF_EFFECT_TEMPLATE): cv.template, vol.Optional(CONF_EFFECT_TEMPLATE): cv.template,
vol.Optional(CONF_GREEN_TEMPLATE): cv.template, vol.Optional(CONF_GREEN_TEMPLATE): cv.template,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean, vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
vol.Optional(CONF_RED_TEMPLATE): cv.template, 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_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_UNIQUE_ID): cv.string, vol.Optional(CONF_UNIQUE_ID): cv.string,
vol.Optional(CONF_DEVICE): mqtt.MQTT_ENTITY_DEVICE_INFO_SCHEMA, vol.Optional(CONF_WHITE_VALUE_TEMPLATE): cv.template,
}).extend(mqtt.MQTT_AVAILABILITY_SCHEMA.schema).extend( }).extend(mqtt.MQTT_AVAILABILITY_SCHEMA.schema).extend(
mqtt.MQTT_JSON_ATTRS_SCHEMA.schema).extend(MQTT_LIGHT_SCHEMA_SCHEMA.schema) mqtt.MQTT_JSON_ATTRS_SCHEMA.schema).extend(MQTT_LIGHT_SCHEMA_SCHEMA.schema)
@ -150,7 +145,7 @@ class MqttTemplate(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
CONF_WHITE_VALUE_TEMPLATE, CONF_WHITE_VALUE_TEMPLATE,
) )
} }
optimistic = config.get(CONF_OPTIMISTIC) optimistic = config[CONF_OPTIMISTIC]
self._optimistic = optimistic \ self._optimistic = optimistic \
or self._topics[CONF_STATE_TOPIC] is None \ or self._topics[CONF_STATE_TOPIC] is None \
or self._templates[CONF_STATE_TEMPLATE] is None or self._templates[CONF_STATE_TEMPLATE] is None
@ -257,7 +252,7 @@ class MqttTemplate(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
self.hass, self._sub_state, self.hass, self._sub_state,
{'state_topic': {'topic': self._topics[CONF_STATE_TOPIC], {'state_topic': {'topic': self._topics[CONF_STATE_TOPIC],
'msg_callback': state_received, 'msg_callback': state_received,
'qos': self._config.get(CONF_QOS)}}) 'qos': self._config[CONF_QOS]}})
if self._optimistic and last_state: if self._optimistic and last_state:
self._state = last_state.state == STATE_ON self._state = last_state.state == STATE_ON
@ -310,7 +305,7 @@ class MqttTemplate(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
@property @property
def name(self): def name(self):
"""Return the name of the entity.""" """Return the name of the entity."""
return self._config.get(CONF_NAME) return self._config[CONF_NAME]
@property @property
def unique_id(self): def unique_id(self):
@ -396,7 +391,7 @@ class MqttTemplate(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
mqtt.async_publish( mqtt.async_publish(
self.hass, self._topics[CONF_COMMAND_TOPIC], self.hass, self._topics[CONF_COMMAND_TOPIC],
self._templates[CONF_COMMAND_ON_TEMPLATE].async_render(**values), self._templates[CONF_COMMAND_ON_TEMPLATE].async_render(**values),
self._config.get(CONF_QOS), self._config.get(CONF_RETAIN) self._config[CONF_QOS], self._config[CONF_RETAIN]
) )
if self._optimistic: if self._optimistic:
@ -417,7 +412,7 @@ class MqttTemplate(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
mqtt.async_publish( mqtt.async_publish(
self.hass, self._topics[CONF_COMMAND_TOPIC], self.hass, self._topics[CONF_COMMAND_TOPIC],
self._templates[CONF_COMMAND_OFF_TEMPLATE].async_render(**values), self._templates[CONF_COMMAND_OFF_TEMPLATE].async_render(**values),
self._config.get(CONF_QOS), self._config.get(CONF_RETAIN) self._config[CONF_QOS], self._config[CONF_RETAIN]
) )
if self._optimistic: if self._optimistic:

View File

@ -88,6 +88,7 @@ light:
brightness_scale: 99 brightness_scale: 99
""" """
import json import json
from unittest import mock
from unittest.mock import ANY, patch from unittest.mock import ANY, patch
from homeassistant.components import light, mqtt from homeassistant.components import light, mqtt
@ -101,6 +102,19 @@ from homeassistant.setup import async_setup_component
from tests.common import ( from tests.common import (
MockConfigEntry, async_fire_mqtt_message, async_mock_mqtt_component, MockConfigEntry, async_fire_mqtt_message, async_mock_mqtt_component,
mock_coro, mock_registry) mock_coro, mock_registry)
from tests.components.light import common
class JsonValidator(object):
"""Helper to compare JSON."""
def __init__(self, jsondata):
"""Constructor."""
self.jsondata = jsondata
def __eq__(self, other):
"""Compare JSON data."""
return json.loads(self.jsondata) == json.loads(other)
async def test_fail_setup_if_no_command_topic(hass, mqtt_mock): async def test_fail_setup_if_no_command_topic(hass, mqtt_mock):
@ -295,7 +309,9 @@ async def test_sending_mqtt_commands_and_optimistic(hass, mqtt_mock):
'brightness': True, 'brightness': True,
'color_temp': True, 'color_temp': True,
'effect': True, 'effect': True,
'hs': True,
'rgb': True, 'rgb': True,
'xy': True,
'white_value': True, 'white_value': True,
'qos': 2 'qos': 2
} }
@ -311,6 +327,65 @@ async def test_sending_mqtt_commands_and_optimistic(hass, mqtt_mock):
assert 191 == state.attributes.get(ATTR_SUPPORTED_FEATURES) assert 191 == state.attributes.get(ATTR_SUPPORTED_FEATURES)
assert state.attributes.get(ATTR_ASSUMED_STATE) assert state.attributes.get(ATTR_ASSUMED_STATE)
common.async_turn_on(hass, 'light.test')
await hass.async_block_till_done()
mqtt_mock.async_publish.assert_called_once_with(
'test_light_rgb/set', '{"state": "ON"}', 2, False)
mqtt_mock.async_publish.reset_mock()
state = hass.states.get('light.test')
assert STATE_ON == state.state
common.async_turn_off(hass, 'light.test')
await hass.async_block_till_done()
mqtt_mock.async_publish.assert_called_once_with(
'test_light_rgb/set', '{"state": "OFF"}', 2, False)
mqtt_mock.async_publish.reset_mock()
state = hass.states.get('light.test')
assert STATE_OFF == state.state
mqtt_mock.reset_mock()
common.async_turn_on(hass, 'light.test',
brightness=50, xy_color=[0.123, 0.123])
common.async_turn_on(hass, 'light.test',
brightness=50, hs_color=[359, 78])
common.async_turn_on(hass, 'light.test', rgb_color=[255, 128, 0],
white_value=80)
await hass.async_block_till_done()
mqtt_mock.async_publish.assert_has_calls([
mock.call(
'test_light_rgb/set',
JsonValidator(
'{"state": "ON", "color": {"r": 0, "g": 123, "b": 255,'
' "x": 0.14, "y": 0.131, "h": 210.824, "s": 100.0},'
' "brightness": 50}'),
2, False),
mock.call(
'test_light_rgb/set',
JsonValidator(
'{"state": "ON", "color": {"r": 255, "g": 56, "b": 59,'
' "x": 0.654, "y": 0.301, "h": 359.0, "s": 78.0},'
' "brightness": 50}'),
2, False),
mock.call(
'test_light_rgb/set',
JsonValidator(
'{"state": "ON", "color": {"r": 255, "g": 128, "b": 0,'
' "x": 0.611, "y": 0.375, "h": 30.118, "s": 100.0},'
' "white_value": 80}'),
2, False),
], any_order=True)
state = hass.states.get('light.test')
assert STATE_ON == state.state
assert (255, 128, 0) == state.attributes['rgb_color']
assert 50 == state.attributes['brightness']
assert (30.118, 100) == state.attributes['hs_color']
assert 80 == state.attributes['white_value']
assert (0.611, 0.375) == state.attributes['xy_color']
async def test_sending_hs_color(hass, mqtt_mock): async def test_sending_hs_color(hass, mqtt_mock):
"""Test light.turn_on with hs color sends hs color parameters.""" """Test light.turn_on with hs color sends hs color parameters."""
@ -320,6 +395,7 @@ async def test_sending_hs_color(hass, mqtt_mock):
'schema': 'json', 'schema': 'json',
'name': 'test', 'name': 'test',
'command_topic': 'test_light_rgb/set', 'command_topic': 'test_light_rgb/set',
'brightness': True,
'hs': True, 'hs': True,
} }
}) })
@ -327,6 +403,170 @@ async def test_sending_hs_color(hass, mqtt_mock):
state = hass.states.get('light.test') state = hass.states.get('light.test')
assert STATE_OFF == state.state assert STATE_OFF == state.state
mqtt_mock.reset_mock()
common.async_turn_on(hass, 'light.test',
brightness=50, xy_color=[0.123, 0.123])
common.async_turn_on(hass, 'light.test',
brightness=50, hs_color=[359, 78])
common.async_turn_on(hass, 'light.test', rgb_color=[255, 128, 0],
white_value=80)
await hass.async_block_till_done()
mqtt_mock.async_publish.assert_has_calls([
mock.call(
'test_light_rgb/set',
JsonValidator(
'{"state": "ON", "color": {"h": 210.824, "s": 100.0},'
' "brightness": 50}'),
0, False),
mock.call(
'test_light_rgb/set',
JsonValidator(
'{"state": "ON", "color": {"h": 359.0, "s": 78.0},'
' "brightness": 50}'),
0, False),
mock.call(
'test_light_rgb/set',
JsonValidator(
'{"state": "ON", "color": {"h": 30.118, "s": 100.0},'
' "white_value": 80}'),
0, False),
], any_order=True)
async def test_sending_rgb_color_no_brightness(hass, mqtt_mock):
"""Test light.turn_on with hs color sends rgb color parameters."""
assert await async_setup_component(hass, light.DOMAIN, {
light.DOMAIN: {
'platform': 'mqtt',
'schema': 'json',
'name': 'test',
'command_topic': 'test_light_rgb/set',
'rgb': True,
}
})
state = hass.states.get('light.test')
assert STATE_OFF == state.state
common.async_turn_on(hass, 'light.test',
brightness=50, xy_color=[0.123, 0.123])
common.async_turn_on(hass, 'light.test',
brightness=50, hs_color=[359, 78])
common.async_turn_on(hass, 'light.test', rgb_color=[255, 128, 0],
brightness=255)
await hass.async_block_till_done()
mqtt_mock.async_publish.assert_has_calls([
mock.call(
'test_light_rgb/set',
JsonValidator(
'{"state": "ON", "color": {"r": 0, "g": 24, "b": 50}}'),
0, False),
mock.call(
'test_light_rgb/set',
JsonValidator(
'{"state": "ON", "color": {"r": 50, "g": 11, "b": 11}}'),
0, False),
mock.call(
'test_light_rgb/set',
JsonValidator(
'{"state": "ON", "color": {"r": 255, "g": 128, "b": 0}}'),
0, False),
], any_order=True)
async def test_sending_rgb_color_with_brightness(hass, mqtt_mock):
"""Test light.turn_on with hs color sends rgb color parameters."""
assert await async_setup_component(hass, light.DOMAIN, {
light.DOMAIN: {
'platform': 'mqtt',
'schema': 'json',
'name': 'test',
'command_topic': 'test_light_rgb/set',
'brightness': True,
'rgb': True,
}
})
state = hass.states.get('light.test')
assert STATE_OFF == state.state
common.async_turn_on(hass, 'light.test',
brightness=50, xy_color=[0.123, 0.123])
common.async_turn_on(hass, 'light.test',
brightness=50, hs_color=[359, 78])
common.async_turn_on(hass, 'light.test', rgb_color=[255, 128, 0],
white_value=80)
await hass.async_block_till_done()
mqtt_mock.async_publish.assert_has_calls([
mock.call(
'test_light_rgb/set',
JsonValidator(
'{"state": "ON", "color": {"r": 0, "g": 123, "b": 255},'
' "brightness": 50}'),
0, False),
mock.call(
'test_light_rgb/set',
JsonValidator(
'{"state": "ON", "color": {"r": 255, "g": 56, "b": 59},'
' "brightness": 50}'),
0, False),
mock.call(
'test_light_rgb/set',
JsonValidator(
'{"state": "ON", "color": {"r": 255, "g": 128, "b": 0},'
' "white_value": 80}'),
0, False),
], any_order=True)
async def test_sending_xy_color(hass, mqtt_mock):
"""Test light.turn_on with hs color sends xy color parameters."""
assert await async_setup_component(hass, light.DOMAIN, {
light.DOMAIN: {
'platform': 'mqtt',
'schema': 'json',
'name': 'test',
'command_topic': 'test_light_rgb/set',
'brightness': True,
'xy': True,
}
})
state = hass.states.get('light.test')
assert STATE_OFF == state.state
common.async_turn_on(hass, 'light.test',
brightness=50, xy_color=[0.123, 0.123])
common.async_turn_on(hass, 'light.test',
brightness=50, hs_color=[359, 78])
common.async_turn_on(hass, 'light.test', rgb_color=[255, 128, 0],
white_value=80)
await hass.async_block_till_done()
mqtt_mock.async_publish.assert_has_calls([
mock.call(
'test_light_rgb/set',
JsonValidator(
'{"state": "ON", "color": {"x": 0.14, "y": 0.131},'
' "brightness": 50}'),
0, False),
mock.call(
'test_light_rgb/set',
JsonValidator(
'{"state": "ON", "color": {"x": 0.654, "y": 0.301},'
' "brightness": 50}'),
0, False),
mock.call(
'test_light_rgb/set',
JsonValidator(
'{"state": "ON", "color": {"x": 0.611, "y": 0.375},'
' "white_value": 80}'),
0, False),
], any_order=True)
async def test_flash_short_and_long(hass, mqtt_mock): async def test_flash_short_and_long(hass, mqtt_mock):
"""Test for flash length being sent when included.""" """Test for flash length being sent when included."""
@ -335,7 +575,6 @@ async def test_flash_short_and_long(hass, mqtt_mock):
'platform': 'mqtt', 'platform': 'mqtt',
'schema': 'json', 'schema': 'json',
'name': 'test', 'name': 'test',
'state_topic': 'test_light_rgb',
'command_topic': 'test_light_rgb/set', 'command_topic': 'test_light_rgb/set',
'flash_time_short': 5, 'flash_time_short': 5,
'flash_time_long': 15, 'flash_time_long': 15,
@ -347,6 +586,26 @@ async def test_flash_short_and_long(hass, mqtt_mock):
assert STATE_OFF == state.state assert STATE_OFF == state.state
assert 40 == state.attributes.get(ATTR_SUPPORTED_FEATURES) assert 40 == state.attributes.get(ATTR_SUPPORTED_FEATURES)
common.async_turn_on(hass, 'light.test', flash='short')
await hass.async_block_till_done()
mqtt_mock.async_publish.assert_called_once_with(
'test_light_rgb/set', JsonValidator(
'{"state": "ON", "flash": 5}'), 0, False)
mqtt_mock.async_publish.reset_mock()
state = hass.states.get('light.test')
assert STATE_ON == state.state
common.async_turn_on(hass, 'light.test', flash='long')
await hass.async_block_till_done()
mqtt_mock.async_publish.assert_called_once_with(
'test_light_rgb/set', JsonValidator(
'{"state": "ON", "flash": 15}'), 0, False)
mqtt_mock.async_publish.reset_mock()
state = hass.states.get('light.test')
assert STATE_ON == state.state
async def test_transition(hass, mqtt_mock): async def test_transition(hass, mqtt_mock):
"""Test for transition time being sent when included.""" """Test for transition time being sent when included."""
@ -355,7 +614,6 @@ async def test_transition(hass, mqtt_mock):
'platform': 'mqtt', 'platform': 'mqtt',
'schema': 'json', 'schema': 'json',
'name': 'test', 'name': 'test',
'state_topic': 'test_light_rgb',
'command_topic': 'test_light_rgb/set', 'command_topic': 'test_light_rgb/set',
'qos': 0 'qos': 0
} }
@ -365,6 +623,26 @@ async def test_transition(hass, mqtt_mock):
assert STATE_OFF == state.state assert STATE_OFF == state.state
assert 40 == state.attributes.get(ATTR_SUPPORTED_FEATURES) assert 40 == state.attributes.get(ATTR_SUPPORTED_FEATURES)
common.async_turn_on(hass, 'light.test', transition=15)
await hass.async_block_till_done()
mqtt_mock.async_publish.assert_called_once_with(
'test_light_rgb/set', JsonValidator(
'{"state": "ON", "transition": 15}'), 0, False)
mqtt_mock.async_publish.reset_mock()
state = hass.states.get('light.test')
assert STATE_ON == state.state
common.async_turn_off(hass, 'light.test', transition=30)
await hass.async_block_till_done()
mqtt_mock.async_publish.assert_called_once_with(
'test_light_rgb/set', JsonValidator(
'{"state": "OFF", "transition": 30}'), 0, False)
mqtt_mock.async_publish.reset_mock()
state = hass.states.get('light.test')
assert STATE_OFF == state.state
async def test_brightness_scale(hass, mqtt_mock): async def test_brightness_scale(hass, mqtt_mock):
"""Test for brightness scaling.""" """Test for brightness scaling."""