From b4cf0e874afeca102780b0936faefd290b72585d Mon Sep 17 00:00:00 2001 From: Oliver van Porten Date: Fri, 20 Nov 2015 22:03:17 +0100 Subject: [PATCH] Support parsing mqtt messages via jsonpath --- homeassistant/components/mqtt/__init__.py | 11 +++++++++++ homeassistant/components/sensor/mqtt.py | 15 ++++++++++++--- homeassistant/components/switch/mqtt.py | 13 +++++++++++-- requirements_all.txt | 1 + 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index cd5b5370175..24a19494d41 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -9,6 +9,8 @@ https://home-assistant.io/components/mqtt/ import logging import os import socket +import json +import jsonpath_rw from homeassistant.exceptions import HomeAssistantError import homeassistant.util as util @@ -127,6 +129,15 @@ def setup(hass, config): return True +class JsonFmtParser(object): + """ Implements a json parser on xpath""" + def __init__(self, jsonpath): + 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 None + + # 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 diff --git a/homeassistant/components/sensor/mqtt.py b/homeassistant/components/sensor/mqtt.py index 2623d2fdcce..f2608bd1657 100644 --- a/homeassistant/components/sensor/mqtt.py +++ b/homeassistant/components/sensor/mqtt.py @@ -7,6 +7,8 @@ For more details about this platform, please refer to the documentation at https://home-assistant.io/components/sensor.mqtt/ """ import logging +import json +import jsonpath_rw from homeassistant.helpers.entity import Entity import homeassistant.components.mqtt as mqtt @@ -31,23 +33,30 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): config.get('name', DEFAULT_NAME), config.get('state_topic'), config.get('qos', DEFAULT_QOS), - config.get('unit_of_measurement'))]) + config.get('unit_of_measurement'), + config.get('state_format'))]) # 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): + def __init__(self, hass, name, state_topic, qos, unit_of_measurement,state_format): self._state = "-" self._hass = hass self._name = name self._state_topic = state_topic self._qos = qos self._unit_of_measurement = unit_of_measurement + self._state_format = state_format + + if self._state_format.startswith('json:'): + self._parser = mqtt.JsonFmtParser(self._state_format[5:]) + else: + self._parser = lambda x: x def message_received(topic, payload, qos): """ A new MQTT message has been received. """ - self._state = payload + self._state = self._parser(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 12d3f486323..a94ebe6b6b1 100644 --- a/homeassistant/components/switch/mqtt.py +++ b/homeassistant/components/switch/mqtt.py @@ -37,14 +37,15 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): config.get('qos', DEFAULT_QOS), config.get('payload_on', DEFAULT_PAYLOAD_ON), config.get('payload_off', DEFAULT_PAYLOAD_OFF), - config.get('optimistic', DEFAULT_OPTIMISTIC))]) + config.get('optimistic', DEFAULT_OPTIMISTIC), + config.get('state_format'))]) # pylint: disable=too-many-arguments, too-many-instance-attributes class MqttSwitch(SwitchDevice): """ Represents a switch that can be togggled using MQTT. """ def __init__(self, hass, name, state_topic, command_topic, qos, - payload_on, payload_off, optimistic): + payload_on, payload_off, optimistic, state_format): self._state = False self._hass = hass self._name = name @@ -54,9 +55,17 @@ class MqttSwitch(SwitchDevice): self._payload_on = payload_on self._payload_off = payload_off self._optimistic = optimistic + + self._state_format = state_format + + if self._state_format.startswith('json:'): + self._parser = mqtt.JsonFmtParser(self._state_format[5:]) + else: + self._parser = lambda x: x def message_received(topic, payload, qos): """ A new MQTT message has been received. """ + payload = self._parser(payload) if payload == self._payload_on: self._state = True self.update_ha_state() diff --git a/requirements_all.txt b/requirements_all.txt index c6b4ae81721..7e15e594313 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -74,6 +74,7 @@ https://github.com/bashwork/pymodbus/archive/d7fc4f1cc975631e0a9011390e8017f64b6 # homeassistant.components.mqtt paho-mqtt==1.1 +jsonpath-rw==1.4.0 # homeassistant.components.notify.pushbullet pushbullet.py==0.9.0