From 7a4f3fe7b85ffdd058f3456ed8fd711d709f4733 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Mon, 28 Jun 2021 14:37:26 +0200 Subject: [PATCH] Filter MQTT light JSON attributes (#52242) --- .../components/mqtt/light/schema_basic.py | 25 +++++++++++++++++++ .../components/mqtt/light/schema_json.py | 4 ++- .../components/mqtt/light/schema_template.py | 3 +++ homeassistant/components/mqtt/mixins.py | 7 +++--- tests/components/mqtt/test_light.py | 11 ++++++++ tests/components/mqtt/test_light_json.py | 11 ++++++++ tests/components/mqtt/test_light_template.py | 11 ++++++++ 7 files changed, 68 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/mqtt/light/schema_basic.py b/homeassistant/components/mqtt/light/schema_basic.py index 214da1dd7bf..c4af68d3044 100644 --- a/homeassistant/components/mqtt/light/schema_basic.py +++ b/homeassistant/components/mqtt/light/schema_basic.py @@ -8,10 +8,14 @@ from homeassistant.components.light import ( ATTR_COLOR_MODE, ATTR_COLOR_TEMP, ATTR_EFFECT, + ATTR_EFFECT_LIST, ATTR_HS_COLOR, + ATTR_MAX_MIREDS, + ATTR_MIN_MIREDS, ATTR_RGB_COLOR, ATTR_RGBW_COLOR, ATTR_RGBWW_COLOR, + ATTR_SUPPORTED_COLOR_MODES, ATTR_WHITE, ATTR_WHITE_VALUE, ATTR_XY_COLOR, @@ -97,6 +101,25 @@ CONF_WHITE_VALUE_STATE_TOPIC = "white_value_state_topic" CONF_WHITE_VALUE_TEMPLATE = "white_value_template" CONF_ON_COMMAND_TYPE = "on_command_type" +MQTT_LIGHT_ATTRIBUTES_BLOCKED = frozenset( + { + ATTR_COLOR_MODE, + ATTR_BRIGHTNESS, + ATTR_COLOR_TEMP, + ATTR_EFFECT, + ATTR_EFFECT_LIST, + ATTR_HS_COLOR, + ATTR_MAX_MIREDS, + ATTR_MIN_MIREDS, + ATTR_RGB_COLOR, + ATTR_RGBW_COLOR, + ATTR_RGBWW_COLOR, + ATTR_SUPPORTED_COLOR_MODES, + ATTR_WHITE_VALUE, + ATTR_XY_COLOR, + } +) + DEFAULT_BRIGHTNESS_SCALE = 255 DEFAULT_NAME = "MQTT LightEntity" DEFAULT_OPTIMISTIC = False @@ -205,6 +228,8 @@ async def async_setup_entity_basic( class MqttLight(MqttEntity, LightEntity, RestoreEntity): """Representation of a MQTT light.""" + _attributes_extra_blocked = MQTT_LIGHT_ATTRIBUTES_BLOCKED + def __init__(self, hass, config, config_entry, discovery_data): """Initialize MQTT light.""" self._brightness = None diff --git a/homeassistant/components/mqtt/light/schema_json.py b/homeassistant/components/mqtt/light/schema_json.py index 0c8080db5d2..1223b79148a 100644 --- a/homeassistant/components/mqtt/light/schema_json.py +++ b/homeassistant/components/mqtt/light/schema_json.py @@ -61,7 +61,7 @@ from ... import mqtt from ..debug_info import log_messages from ..mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity from .schema import MQTT_LIGHT_SCHEMA_SCHEMA -from .schema_basic import CONF_BRIGHTNESS_SCALE +from .schema_basic import CONF_BRIGHTNESS_SCALE, MQTT_LIGHT_ATTRIBUTES_BLOCKED _LOGGER = logging.getLogger(__name__) @@ -157,6 +157,8 @@ async def async_setup_entity_json( class MqttLightJson(MqttEntity, LightEntity, RestoreEntity): """Representation of a MQTT JSON light.""" + _attributes_extra_blocked = MQTT_LIGHT_ATTRIBUTES_BLOCKED + def __init__(self, hass, config, config_entry, discovery_data): """Initialize MQTT JSON light.""" self._state = False diff --git a/homeassistant/components/mqtt/light/schema_template.py b/homeassistant/components/mqtt/light/schema_template.py index d2df37828f1..9a23d9ea2f9 100644 --- a/homeassistant/components/mqtt/light/schema_template.py +++ b/homeassistant/components/mqtt/light/schema_template.py @@ -37,6 +37,7 @@ from ... import mqtt from ..debug_info import log_messages from ..mixins import MQTT_ENTITY_COMMON_SCHEMA, MqttEntity from .schema import MQTT_LIGHT_SCHEMA_SCHEMA +from .schema_basic import MQTT_LIGHT_ATTRIBUTES_BLOCKED _LOGGER = logging.getLogger(__name__) @@ -93,6 +94,8 @@ async def async_setup_entity_template( class MqttLightTemplate(MqttEntity, LightEntity, RestoreEntity): """Representation of a MQTT Template light.""" + _attributes_extra_blocked = MQTT_LIGHT_ATTRIBUTES_BLOCKED + def __init__(self, hass, config, config_entry, discovery_data): """Initialize a MQTT Template light.""" self._state = False diff --git a/homeassistant/components/mqtt/mixins.py b/homeassistant/components/mqtt/mixins.py index 46c4a88e8fe..b0c8b573b37 100644 --- a/homeassistant/components/mqtt/mixins.py +++ b/homeassistant/components/mqtt/mixins.py @@ -194,12 +194,13 @@ async def async_setup_entry_helper(hass, domain, async_setup, schema): class MqttAttributes(Entity): """Mixin used for platforms that support JSON attributes.""" - def __init__(self, config: dict, extra_blocked_attributes: list = None) -> None: + _attributes_extra_blocked = frozenset() + + def __init__(self, config: dict) -> None: """Initialize the JSON attributes mixin.""" self._attributes = None self._attributes_sub_state = None self._attributes_config = config - self._extra_blocked_attributes = extra_blocked_attributes or [] async def async_added_to_hass(self) -> None: """Subscribe MQTT events.""" @@ -230,7 +231,7 @@ class MqttAttributes(Entity): k: v for k, v in json_dict.items() if k not in MQTT_ATTRIBUTES_BLOCKED - and k not in self._extra_blocked_attributes + and k not in self._attributes_extra_blocked } self._attributes = filtered_dict self.async_write_ha_state() diff --git a/tests/components/mqtt/test_light.py b/tests/components/mqtt/test_light.py index efd3b1b2424..7341eeb67fc 100644 --- a/tests/components/mqtt/test_light.py +++ b/tests/components/mqtt/test_light.py @@ -161,6 +161,9 @@ import pytest from homeassistant import config as hass_config from homeassistant.components import light +from homeassistant.components.mqtt.light.schema_basic import ( + MQTT_LIGHT_ATTRIBUTES_BLOCKED, +) from homeassistant.const import ( ATTR_ASSUMED_STATE, ATTR_SUPPORTED_FEATURES, @@ -190,6 +193,7 @@ from .test_common import ( help_test_entity_id_update_subscriptions, help_test_setting_attribute_via_mqtt_json_message, help_test_setting_attribute_with_template, + help_test_setting_blocked_attribute_via_mqtt_json_message, help_test_unique_id, help_test_update_with_json_attrs_bad_JSON, help_test_update_with_json_attrs_not_dict, @@ -2712,6 +2716,13 @@ async def test_setting_attribute_via_mqtt_json_message(hass, mqtt_mock): ) +async def test_setting_blocked_attribute_via_mqtt_json_message(hass, mqtt_mock): + """Test the setting of attribute via MQTT with JSON payload.""" + await help_test_setting_blocked_attribute_via_mqtt_json_message( + hass, mqtt_mock, light.DOMAIN, DEFAULT_CONFIG, MQTT_LIGHT_ATTRIBUTES_BLOCKED + ) + + async def test_setting_attribute_with_template(hass, mqtt_mock): """Test the setting of attribute via MQTT with JSON payload.""" await help_test_setting_attribute_with_template( diff --git a/tests/components/mqtt/test_light_json.py b/tests/components/mqtt/test_light_json.py index f4bf11df026..8aba08f60d7 100644 --- a/tests/components/mqtt/test_light_json.py +++ b/tests/components/mqtt/test_light_json.py @@ -93,6 +93,9 @@ from unittest.mock import call, patch import pytest from homeassistant.components import light +from homeassistant.components.mqtt.light.schema_basic import ( + MQTT_LIGHT_ATTRIBUTES_BLOCKED, +) from homeassistant.const import ( ATTR_ASSUMED_STATE, ATTR_SUPPORTED_FEATURES, @@ -121,6 +124,7 @@ from .test_common import ( help_test_entity_id_update_subscriptions, help_test_setting_attribute_via_mqtt_json_message, help_test_setting_attribute_with_template, + help_test_setting_blocked_attribute_via_mqtt_json_message, help_test_unique_id, help_test_update_with_json_attrs_bad_JSON, help_test_update_with_json_attrs_not_dict, @@ -1714,6 +1718,13 @@ async def test_setting_attribute_via_mqtt_json_message(hass, mqtt_mock): ) +async def test_setting_blocked_attribute_via_mqtt_json_message(hass, mqtt_mock): + """Test the setting of attribute via MQTT with JSON payload.""" + await help_test_setting_blocked_attribute_via_mqtt_json_message( + hass, mqtt_mock, light.DOMAIN, DEFAULT_CONFIG, MQTT_LIGHT_ATTRIBUTES_BLOCKED + ) + + async def test_setting_attribute_with_template(hass, mqtt_mock): """Test the setting of attribute via MQTT with JSON payload.""" await help_test_setting_attribute_with_template( diff --git a/tests/components/mqtt/test_light_template.py b/tests/components/mqtt/test_light_template.py index 2e726d40ef1..2dabf0b7e46 100644 --- a/tests/components/mqtt/test_light_template.py +++ b/tests/components/mqtt/test_light_template.py @@ -31,6 +31,9 @@ from unittest.mock import patch import pytest from homeassistant.components import light +from homeassistant.components.mqtt.light.schema_basic import ( + MQTT_LIGHT_ATTRIBUTES_BLOCKED, +) from homeassistant.const import ( ATTR_ASSUMED_STATE, ATTR_SUPPORTED_FEATURES, @@ -59,6 +62,7 @@ from .test_common import ( help_test_entity_id_update_subscriptions, help_test_setting_attribute_via_mqtt_json_message, help_test_setting_attribute_with_template, + help_test_setting_blocked_attribute_via_mqtt_json_message, help_test_unique_id, help_test_update_with_json_attrs_bad_JSON, help_test_update_with_json_attrs_not_dict, @@ -870,6 +874,13 @@ async def test_setting_attribute_via_mqtt_json_message(hass, mqtt_mock): ) +async def test_setting_blocked_attribute_via_mqtt_json_message(hass, mqtt_mock): + """Test the setting of attribute via MQTT with JSON payload.""" + await help_test_setting_blocked_attribute_via_mqtt_json_message( + hass, mqtt_mock, light.DOMAIN, DEFAULT_CONFIG, MQTT_LIGHT_ATTRIBUTES_BLOCKED + ) + + async def test_setting_attribute_with_template(hass, mqtt_mock): """Test the setting of attribute via MQTT with JSON payload.""" await help_test_setting_attribute_with_template(