diff --git a/homeassistant/components/sensor/serial.py b/homeassistant/components/sensor/serial.py index 6f01a8f856b..7bed4b25011 100644 --- a/homeassistant/components/sensor/serial.py +++ b/homeassistant/components/sensor/serial.py @@ -6,12 +6,14 @@ https://home-assistant.io/components/sensor.serial/ """ import asyncio import logging +import json import voluptuous as vol import homeassistant.helpers.config_validation as cv from homeassistant.components.sensor import PLATFORM_SCHEMA -from homeassistant.const import CONF_NAME, EVENT_HOMEASSISTANT_STOP +from homeassistant.const import ( + CONF_NAME, CONF_VALUE_TEMPLATE, EVENT_HOMEASSISTANT_STOP) from homeassistant.helpers.entity import Entity REQUIREMENTS = ['pyserial-asyncio==0.4'] @@ -29,6 +31,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Optional(CONF_BAUDRATE, default=DEFAULT_BAUDRATE): cv.positive_int, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + vol.Optional(CONF_VALUE_TEMPLATE): cv.template, }) @@ -39,7 +42,11 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): port = config.get(CONF_SERIAL_PORT) baudrate = config.get(CONF_BAUDRATE) - sensor = SerialSensor(name, port, baudrate) + value_template = config.get(CONF_VALUE_TEMPLATE) + if value_template is not None: + value_template.hass = hass + + sensor = SerialSensor(name, port, baudrate, value_template) hass.bus.async_listen_once( EVENT_HOMEASSISTANT_STOP, sensor.stop_serial_read()) @@ -49,13 +56,15 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): class SerialSensor(Entity): """Representation of a Serial sensor.""" - def __init__(self, name, port, baudrate): + def __init__(self, name, port, baudrate, value_template): """Initialize the Serial sensor.""" self._name = name self._state = None self._port = port self._baudrate = baudrate self._serial_loop_task = None + self._template = value_template + self._attributes = [] @asyncio.coroutine def async_added_to_hass(self): @@ -71,7 +80,20 @@ class SerialSensor(Entity): url=device, baudrate=rate, **kwargs) while True: line = yield from reader.readline() - self._state = line.decode('utf-8').strip() + line = line.decode('utf-8').strip() + + try: + data = json.loads(line) + if isinstance(data, dict): + self._attributes = data + except ValueError: + pass + + if self._template is not None: + line = self._template.async_render_with_possible_json_value( + line) + + self._state = line self.async_schedule_update_ha_state() @asyncio.coroutine @@ -90,6 +112,11 @@ class SerialSensor(Entity): """No polling needed.""" return False + @property + def state_attributes(self): + """Return the attributes of the entity (if any JSON present).""" + return self._attributes + @property def state(self): """Return the state of the sensor."""