From 9a9ecb59165192a88c700412e65c21f1bca7d401 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen <paulus@paulusschoutsen.nl> Date: Thu, 10 Dec 2015 21:39:01 -0800 Subject: [PATCH] Migrate MQTT from jsonpath to templates --- homeassistant/components/mqtt/__init__.py | 30 +------------------ .../components/rollershutter/mqtt.py | 16 ++++++---- homeassistant/components/sensor/mqtt.py | 12 +++++--- homeassistant/components/switch/mqtt.py | 11 ++++--- homeassistant/const.py | 2 ++ tests/components/sensor/test_mqtt.py | 3 +- tests/components/switch/test_mqtt.py | 2 +- 7 files changed, 30 insertions(+), 46 deletions(-) diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index 2c5dbf82923..37a7a63c72b 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -6,7 +6,6 @@ MQTT component, using paho-mqtt. For more details about this component, please refer to the documentation at https://home-assistant.io/components/mqtt/ """ -import json import logging import os import socket @@ -33,7 +32,7 @@ DEFAULT_RETAIN = False SERVICE_PUBLISH = 'publish' EVENT_MQTT_MESSAGE_RECEIVED = 'MQTT_MESSAGE_RECEIVED' -REQUIREMENTS = ['paho-mqtt==1.1', 'jsonpath-rw==1.4.0'] +REQUIREMENTS = ['paho-mqtt==1.1'] CONF_BROKER = 'broker' CONF_PORT = 'port' @@ -136,33 +135,6 @@ def setup(hass, config): return True -# pylint: disable=too-few-public-methods -class _JsonFmtParser(object): - """ Implements a JSON parser on xpath. """ - def __init__(self, jsonpath): - import jsonpath_rw - self._expr = jsonpath_rw.parse(jsonpath) - - def __call__(self, payload): - match = self._expr.find(json.loads(payload)) - return match[0].value if len(match) > 0 else payload - - -# pylint: disable=too-few-public-methods -class FmtParser(object): - """ Wrapper for all supported formats. """ - def __init__(self, fmt): - self._parse = lambda x: x - if fmt: - if fmt.startswith('json:'): - self._parse = _JsonFmtParser(fmt[5:]) - - def __call__(self, payload): - return self._parse(payload) - - -# This is based on one of the paho-mqtt examples: -# http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.python.git/tree/examples/sub-class.py # pylint: disable=too-many-arguments class MQTT(object): """ Implements messaging service for MQTT. """ diff --git a/homeassistant/components/rollershutter/mqtt.py b/homeassistant/components/rollershutter/mqtt.py index f5eb5652516..2951d772be0 100644 --- a/homeassistant/components/rollershutter/mqtt.py +++ b/homeassistant/components/rollershutter/mqtt.py @@ -8,7 +8,10 @@ https://home-assistant.io/components/rollershutter.mqtt/ """ import logging import homeassistant.components.mqtt as mqtt +from homeassistant.const import CONF_VALUE_TEMPLATE from homeassistant.components.rollershutter import RollershutterDevice +from homeassistant.util import template + _LOGGER = logging.getLogger(__name__) DEPENDENCIES = ['mqtt'] @@ -36,14 +39,14 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): config.get('payload_up', DEFAULT_PAYLOAD_UP), config.get('payload_down', DEFAULT_PAYLOAD_DOWN), config.get('payload_stop', DEFAULT_PAYLOAD_STOP), - config.get('state_format'))]) + config.get(CONF_VALUE_TEMPLATE))]) # pylint: disable=too-many-arguments, too-many-instance-attributes class MqttRollershutter(RollershutterDevice): """ Represents a rollershutter that can be controlled using MQTT. """ def __init__(self, hass, name, state_topic, command_topic, qos, - payload_up, payload_down, payload_stop, state_format): + payload_up, payload_down, payload_stop, value_template): self._state = None self._hass = hass self._name = name @@ -53,16 +56,17 @@ class MqttRollershutter(RollershutterDevice): self._payload_up = payload_up self._payload_down = payload_down self._payload_stop = payload_stop - self._parse = mqtt.FmtParser(state_format) if self._state_topic is None: return def message_received(topic, payload, qos): """ A new MQTT message has been received. """ - value = self._parse(payload) - if value.isnumeric() and 0 <= int(value) <= 100: - self._state = int(value) + if value_template is not None: + payload = template.render_with_possible_json_value( + hass, value_template, payload) + if payload.isnumeric() and 0 <= int(payload) <= 100: + self._state = int(payload) self.update_ha_state() else: _LOGGER.warning( diff --git a/homeassistant/components/sensor/mqtt.py b/homeassistant/components/sensor/mqtt.py index 2bbed97e40c..8cf2569acd5 100644 --- a/homeassistant/components/sensor/mqtt.py +++ b/homeassistant/components/sensor/mqtt.py @@ -7,7 +7,9 @@ For more details about this platform, please refer to the documentation at https://home-assistant.io/components/sensor.mqtt/ """ import logging +from homeassistant.const import CONF_VALUE_TEMPLATE from homeassistant.helpers.entity import Entity +from homeassistant.util import template import homeassistant.components.mqtt as mqtt _LOGGER = logging.getLogger(__name__) @@ -32,25 +34,27 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): config.get('state_topic'), config.get('qos', DEFAULT_QOS), config.get('unit_of_measurement'), - config.get('state_format'))]) + config.get(CONF_VALUE_TEMPLATE))]) # pylint: disable=too-many-arguments, too-many-instance-attributes class MqttSensor(Entity): """ Represents a sensor that can be updated using MQTT. """ def __init__(self, hass, name, state_topic, qos, unit_of_measurement, - state_format): + value_template): self._state = "-" self._hass = hass self._name = name self._state_topic = state_topic self._qos = qos self._unit_of_measurement = unit_of_measurement - self._parse = mqtt.FmtParser(state_format) def message_received(topic, payload, qos): """ A new MQTT message has been received. """ - self._state = self._parse(payload) + if value_template is not None: + payload = template.render_with_possible_json_value( + hass, value_template, payload) + self._state = payload self.update_ha_state() mqtt.subscribe(hass, self._state_topic, message_received, self._qos) diff --git a/homeassistant/components/switch/mqtt.py b/homeassistant/components/switch/mqtt.py index 7b973799eed..c27709cc522 100644 --- a/homeassistant/components/switch/mqtt.py +++ b/homeassistant/components/switch/mqtt.py @@ -8,7 +8,9 @@ https://home-assistant.io/components/switch.mqtt/ """ import logging import homeassistant.components.mqtt as mqtt +from homeassistant.const import CONF_VALUE_TEMPLATE from homeassistant.components.switch import SwitchDevice +from homeassistant.util import template _LOGGER = logging.getLogger(__name__) @@ -40,14 +42,14 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): config.get('payload_on', DEFAULT_PAYLOAD_ON), config.get('payload_off', DEFAULT_PAYLOAD_OFF), config.get('optimistic', DEFAULT_OPTIMISTIC), - config.get('state_format'))]) + config.get(CONF_VALUE_TEMPLATE))]) # pylint: disable=too-many-arguments, too-many-instance-attributes class MqttSwitch(SwitchDevice): """ Represents a switch that can be toggled using MQTT. """ def __init__(self, hass, name, state_topic, command_topic, qos, retain, - payload_on, payload_off, optimistic, state_format): + payload_on, payload_off, optimistic, value_template): self._state = False self._hass = hass self._name = name @@ -58,11 +60,12 @@ class MqttSwitch(SwitchDevice): self._payload_on = payload_on self._payload_off = payload_off self._optimistic = optimistic - self._parse = mqtt.FmtParser(state_format) def message_received(topic, payload, qos): """ A new MQTT message has been received. """ - payload = self._parse(payload) + if value_template is not None: + payload = template.render_with_possible_json_value( + hass, value_template, payload) if payload == self._payload_on: self._state = True self.update_ha_state() diff --git a/homeassistant/const.py b/homeassistant/const.py index cdb56e60131..287ae7998d2 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -25,6 +25,8 @@ CONF_PASSWORD = "password" CONF_API_KEY = "api_key" CONF_ACCESS_TOKEN = "access_token" +CONF_VALUE_TEMPLATE = "value_template" + # #### EVENTS #### EVENT_HOMEASSISTANT_START = "homeassistant_start" EVENT_HOMEASSISTANT_STOP = "homeassistant_stop" diff --git a/tests/components/sensor/test_mqtt.py b/tests/components/sensor/test_mqtt.py index 0c17b95e212..ce98a9399a5 100644 --- a/tests/components/sensor/test_mqtt.py +++ b/tests/components/sensor/test_mqtt.py @@ -47,7 +47,7 @@ class TestSensorMQTT(unittest.TestCase): 'name': 'test', 'state_topic': 'test-topic', 'unit_of_measurement': 'fav unit', - 'state_format': 'json:val' + 'value_template': '{{ value_json.val }}' } })) @@ -56,4 +56,3 @@ class TestSensorMQTT(unittest.TestCase): state = self.hass.states.get('sensor.test') self.assertEqual('100', state.state) - diff --git a/tests/components/switch/test_mqtt.py b/tests/components/switch/test_mqtt.py index 2cfe29c2910..b7c20e5ff94 100644 --- a/tests/components/switch/test_mqtt.py +++ b/tests/components/switch/test_mqtt.py @@ -90,7 +90,7 @@ class TestSensorMQTT(unittest.TestCase): 'command_topic': 'command-topic', 'payload_on': 'beer on', 'payload_off': 'beer off', - 'state_format': 'json:val' + 'value_template': '{{ value_json.val }}' } })) -- GitLab