From 70ba5eb0ef9b9f879138104d3e522515d0e67321 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Fri, 19 Apr 2019 05:55:10 +0200 Subject: [PATCH] Add json_attributes_template (#22981) --- homeassistant/components/mqtt/__init__.py | 14 ++++++++++++-- tests/components/mqtt/test_sensor.py | 21 +++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index e226e966b09..3de53145cfc 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -69,6 +69,7 @@ CONF_AVAILABILITY_TOPIC = 'availability_topic' CONF_PAYLOAD_AVAILABLE = 'payload_available' CONF_PAYLOAD_NOT_AVAILABLE = 'payload_not_available' CONF_JSON_ATTRS_TOPIC = 'json_attributes_topic' +CONF_JSON_ATTRS_TEMPLATE = 'json_attributes_template' CONF_QOS = 'qos' CONF_RETAIN = 'retain' @@ -242,6 +243,7 @@ MQTT_ENTITY_DEVICE_INFO_SCHEMA = vol.All(vol.Schema({ MQTT_JSON_ATTRS_SCHEMA = vol.Schema({ vol.Optional(CONF_JSON_ATTRS_TOPIC): valid_subscribe_topic, + vol.Optional(CONF_JSON_ATTRS_TEMPLATE): cv.template, }) MQTT_BASE_PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA.extend(SCHEMA_BASE) @@ -908,10 +910,18 @@ class MqttAttributes(Entity): """(Re)Subscribe to topics.""" from .subscription import async_subscribe_topics + attr_tpl = self._attributes_config.get(CONF_JSON_ATTRS_TEMPLATE) + if attr_tpl is not None: + attr_tpl.hass = self.hass + @callback def attributes_message_received(msg: Message) -> None: try: - json_dict = json.loads(msg.payload) + payload = msg.payload + if attr_tpl is not None: + payload = attr_tpl.async_render_with_possible_json_value( + payload) + json_dict = json.loads(payload) if isinstance(json_dict, dict): self._attributes = json_dict self.async_write_ha_state() @@ -919,7 +929,7 @@ class MqttAttributes(Entity): _LOGGER.warning("JSON result was not a dictionary") self._attributes = None except ValueError: - _LOGGER.warning("Erroneous JSON: %s", msg.payload) + _LOGGER.warning("Erroneous JSON: %s", payload) self._attributes = None self._attributes_sub_state = await async_subscribe_topics( diff --git a/tests/components/mqtt/test_sensor.py b/tests/components/mqtt/test_sensor.py index 027135e8a7a..45267484211 100644 --- a/tests/components/mqtt/test_sensor.py +++ b/tests/components/mqtt/test_sensor.py @@ -384,6 +384,27 @@ async def test_setting_attribute_via_mqtt_json_message(hass, mqtt_mock): assert '100' == state.attributes.get('val') +async def test_setting_attribute_with_template(hass, mqtt_mock): + """Test the setting of attribute via MQTT with JSON payload.""" + assert await async_setup_component(hass, sensor.DOMAIN, { + sensor.DOMAIN: { + 'platform': 'mqtt', + 'name': 'test', + 'state_topic': 'test-topic', + 'json_attributes_topic': 'attr-topic', + 'json_attributes_template': "{{ value_json['Timer1'] | tojson }}" + } + }) + + async_fire_mqtt_message(hass, 'attr-topic', json.dumps( + {"Timer1": {"Arm": 0, "Time": "22:18"}})) + await hass.async_block_till_done() + state = hass.states.get('sensor.test') + + assert 0 == state.attributes.get('Arm') + assert '22:18' == state.attributes.get('Time') + + async def test_update_with_json_attrs_not_dict(hass, mqtt_mock, caplog): """Test attributes get extracted from a JSON result.""" assert await async_setup_component(hass, sensor.DOMAIN, {