add JSON processing capabilities to sensor_serial (#10476)

* add JSON processing capabilities

* format fixes

* format fixes

* Fix according to @fabaff comment

* reverting last commit to a more sane approach

* docstring...

* still docstring...

* passed script/lint

* downgrade exception

JSONDecodeError was only introduced in Python3.5

Since we are still supporting 3.4 ValueError is the parent class of
JSONDecodeError
pull/10510/head
Diogo Gomes 2017-11-10 09:49:30 +00:00 committed by Fabian Affolter
parent 143d9492b2
commit 9bfdff0be1
1 changed files with 31 additions and 4 deletions

View File

@ -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."""